// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package logger

import (
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"os"
	"runtime"
	"strings"
	"sync"
	"sync/atomic"
	"syscall/zx"

	"app/context"

	logger_fidl "fidl/fuchsia/logger"
)

var (
	ErrNotInitialized   = errors.New("default logger not initialized")
	ErrInitialized      = errors.New("default logger is already initialized")
	ErrInvalidArg       = errors.New("Invalid arguments to logger")
	ErrMsgTooLongString = "Msg too long. it was truncated"
)

// This is returned when msg is truncated. It contains the truncated part.
type ErrMsgTooLong struct {
	Msg string // rest of the message
}

func (e ErrMsgTooLong) Error() string {
	return ErrMsgTooLongString
}

const (
	MAX_GLOBAL_TAGS   = 4
	MAX_TAG_LEN       = 63
	SOCKET_BUFFER_LEN = 2032
	SOCKET_DATAGRAM   = 1 << 0
)

type LogLevel int32

const (
	InfoLevel LogLevel = iota
	WarningLevel
	ErrorLevel
	FatalLevel
)

func (ll LogLevel) String() string {
	switch ll {
	case InfoLevel:
		return "INFO"
	case WarningLevel:
		return "WARNING"
	case ErrorLevel:
		return "ERROR"
	case FatalLevel:
		return "FATAL"
	default:
		if int(ll) < 0 {
			return fmt.Sprintf("VLOG(%d)", -(int(ll)))
		}
		return "INVALID"
	}
}

type LogInitOptions struct {
	Connector         *context.Connector
	Loglevel          LogLevel
	ConsoleWriter     io.Writer
	LogServiceChannel *zx.Socket
	Tags              []string
}

func GetDefaultInitOptions() LogInitOptions {
	return LogInitOptions{
		Loglevel:          InfoLevel,
		ConsoleWriter:     nil,
		LogServiceChannel: nil,
		Tags:              nil,
	}
}

type Logger struct {
	logLevel    LogLevel
	tags        []string
	socket      *zx.Socket
	writer      atomic.Value
	tagString   string
	pid         uint64
	droppedLogs uint32
	fallbackMux sync.Mutex
}

func (l *Logger) setTags(tags []string) error {
	if len(tags) > MAX_GLOBAL_TAGS {
		return ErrInvalidArg
	}
	for _, tag := range tags {
		if len(tag) > MAX_TAG_LEN {
			return ErrInvalidArg
		}
	}
	if l.writer.Load() != nil {
		l.tagString = strings.Join(tags, ", ")
	}
	l.tags = tags
	return nil
}

func (l *Logger) ActivateFallbackMode() {
	l.fallbackMux.Lock()
	defer l.fallbackMux.Unlock()
	if l.writer.Load() != nil {
		return //already active
	}
	if l.tagString == "" {
		l.tagString = strings.Join(l.tags, ", ")
	}
	l.writer.Store(os.Stderr)
}

func connectToLogger(c *context.Connector) (*zx.Socket, error) {
	sin, sout, err := zx.NewSocket(SOCKET_DATAGRAM)
	if err != nil {
		return nil, err
	}
	req, ls, err := logger_fidl.NewLogSinkInterfaceRequest()
	if err != nil {
		return nil, err
	}
	c.ConnectToEnvService(req)
	err = ls.Connect(sout)
	ls.Close()
	return &sin, err
}

func NewLogger(options LogInitOptions) (*Logger, error) {
	l := Logger{
		logLevel: options.Loglevel,
		socket:   options.LogServiceChannel,
		pid:      uint64(os.Getpid()),
	}
	if options.ConsoleWriter == nil && options.LogServiceChannel == nil {
		if options.Connector == nil {
			return nil, fmt.Errorf("Init Error: Writer, LogServiceChannel or Connector needs to be provided")
		}
		if sock, err := connectToLogger(options.Connector); err != nil {
			fmt.Fprintf(os.Stderr, "not able to conenct to log sink, will write logs to stderr: %s", err)
			l.writer.Store(os.Stderr)
		} else {
			l.socket = sock
		}
	} else if options.ConsoleWriter != nil {
		l.writer.Store(options.ConsoleWriter)
	}
	if err := l.setTags(options.Tags); err != nil {
		return nil, err
	}
	return &l, nil
}

func (l *Logger) logToWriter(writer io.Writer, time zx.Time, logLevel LogLevel, tag, msg string) error {
	if len(l.tagString) != 0 {
		if len(tag) != 0 {
			tag = fmt.Sprintf("%s, %s", l.tagString, tag)
		} else {
			tag = l.tagString
		}
	}
	_, err := io.WriteString(writer, fmt.Sprintf("[%05d.%06d][%d][0][%s] %s: %s\n", time/1000000000, (time/1000)%1000000, l.pid, tag, logLevel, msg))
	return err
}

func (l *Logger) logToSocket(time zx.Time, logLevel LogLevel, tag, msg string) error {
	var buffer [SOCKET_BUFFER_LEN]byte
	binary.LittleEndian.PutUint64(buffer[0:8], l.pid)
	binary.LittleEndian.PutUint64(buffer[8:16], 0) // golang doesn't have tid
	binary.LittleEndian.PutUint64(buffer[16:24], uint64(time))
	binary.LittleEndian.PutUint32(buffer[24:28], uint32(logLevel))
	binary.LittleEndian.PutUint32(buffer[28:32], atomic.LoadUint32(&l.droppedLogs))
	pos := 32

	// Write global tags
	for _, tag := range l.tags {
		length := len(tag)
		if length == 0 {
			continue
		}
		buffer[pos] = byte(length)
		pos = pos + 1
		copy(buffer[pos:pos+length], tag)
		pos = pos + length
	}

	// Write local tags
	if len(tag) != 0 {
		length := len(tag)
		buffer[pos] = byte(length)
		pos = pos + 1
		copy(buffer[pos:pos+length], tag)
		pos = pos + length
	}

	//write msg
	buffer[pos] = 0
	pos = pos + 1
	errMsgTooLong := ErrMsgTooLong{""}
	if len(msg) >= SOCKET_BUFFER_LEN-pos {
		// truncate
		errMsgTooLong.Msg = msg[SOCKET_BUFFER_LEN-pos-4:]
		msg = msg[:SOCKET_BUFFER_LEN-pos-4]
		copy(buffer[pos:], msg)
		copy(buffer[pos+len(msg):], "...")
		pos = pos + len(msg) + 3
	} else {
		copy(buffer[pos:], msg)
		pos = pos + len(msg)
	}

	buffer[pos] = 0
	if _, err := l.socket.Write(buffer[:pos+1], 0); err != nil {
		atomic.AddUint32(&l.droppedLogs, 1)
		return err
	}
	if errMsgTooLong.Msg != "" {
		return errMsgTooLong
	}
	return nil
}

func (l *Logger) logf(callDepth int, logLevel LogLevel, tag string, format string, a ...interface{}) error {
	if l.logLevel > logLevel {
		return nil
	}
	time := zx.Sys_clock_get(0) //MONOTONIC
	msg := fmt.Sprintf(format, a...)
	if logLevel >= ErrorLevel {
		_, file, line, ok := runtime.Caller(callDepth)
		if !ok {
			file = "???"
			line = 0
		} else {
			short := file
			for i := len(file) - 1; i > 0; i-- {
				if file[i] == '/' {
					short = file[i+1:]
					break
				}
			}
			file = short
		}
		msg = fmt.Sprintf("%s(%d): %s ", file, line, msg)
	}
	if len(tag) > MAX_TAG_LEN {
		tag = tag[:MAX_TAG_LEN]
	}
	if logLevel == FatalLevel {
		defer os.Exit(1)
	}
	w := l.writer.Load()
	if w != nil {
		return l.logToWriter(w.(io.Writer), time, logLevel, tag, msg)
	} else {
		if err := l.logToSocket(time, logLevel, tag, msg); err != nil {
			if status, ok := err.(zx.Error); ok {
				if status.Status == zx.ErrPeerClosed || status.Status == zx.ErrBadState {
					l.ActivateFallbackMode()
					w = l.writer.Load()
					if w != nil {
						return l.logToWriter(w.(io.Writer), time, logLevel, tag, msg)
					}
				}
			}
			return err
		}
	}
	return nil
}

func (l *Logger) SetSeverity(logLevel LogLevel) {
	l.logLevel = logLevel
}

func (l *Logger) SetVerbosity(verbosity int) {
	l.logLevel = LogLevel(-verbosity)
}

func (l *Logger) Infof(format string, a ...interface{}) error {
	return l.logf(2, InfoLevel, "", format, a...)
}

func (l *Logger) Warnf(format string, a ...interface{}) error {
	return l.logf(2, WarningLevel, "", format, a...)
}

func (l *Logger) Errorf(format string, a ...interface{}) error {
	return l.logf(2, ErrorLevel, "", format, a...)
}

func (l *Logger) Fatalf(format string, a ...interface{}) error {
	return l.logf(2, FatalLevel, "", format, a...)
}

func (l *Logger) VLogf(verbosity int, format string, a ...interface{}) error {
	return l.logf(2, LogLevel(-verbosity), "", format, a...)
}

func (l *Logger) InfoTf(tag, format string, a ...interface{}) error {
	return l.logf(2, InfoLevel, tag, format, a...)
}

func (l *Logger) WarnTf(tag, format string, a ...interface{}) error {
	return l.logf(2, WarningLevel, tag, format, a...)
}

func (l *Logger) ErrorTf(tag, format string, a ...interface{}) error {
	return l.logf(2, ErrorLevel, tag, format, a...)
}

func (l *Logger) FatalTf(tag, format string, a ...interface{}) error {
	return l.logf(2, FatalLevel, tag, format, a...)
}

func (l *Logger) VLogTf(verbosity int, tag, format string, a ...interface{}) error {
	return l.logf(2, LogLevel(-verbosity), tag, format, a...)
}

var defaultLogger *Logger

func logf(callDepth int, logLevel LogLevel, tag string, format string, a ...interface{}) error {
	l := GetDefaultLogger()
	if l != nil {
		return l.logf(callDepth+1, logLevel, tag, format, a...)
	} else {
		return ErrNotInitialized
	}
}

// Public APIs for default logger

func GetDefaultLogger() *Logger {
	return defaultLogger
}

func InitDefaultLogger(c *context.Connector) error {
	options := GetDefaultInitOptions()
	options.Connector = c
	return InitDefaultLoggerWithConfig(options)
}

func InitDefaultLoggerWithTags(c *context.Connector, tags ...string) error {
	o := GetDefaultInitOptions()
	o.Tags = tags
	o.Connector = c
	return InitDefaultLoggerWithConfig(o)
}

func InitDefaultLoggerWithConfig(options LogInitOptions) error {
	if defaultLogger != nil {
		return ErrInitialized
	}

	if l, err := NewLogger(options); err != nil {
		return err
	} else {
		defaultLogger = l
	}
	return nil
}

func SetSeverity(logLevel LogLevel) {
	if l := GetDefaultLogger(); l != nil {
		l.logLevel = logLevel
	}
}

func SetVerbosity(verbosity int) {
	if l := GetDefaultLogger(); l != nil {
		l.logLevel = LogLevel(-verbosity)
	}
}

func Infof(format string, a ...interface{}) error {
	return logf(2, InfoLevel, "", format, a...)
}

func Warnf(format string, a ...interface{}) error {
	return logf(2, WarningLevel, "", format, a...)
}

func Errorf(format string, a ...interface{}) error {
	return logf(2, ErrorLevel, "", format, a...)
}

func Fatalf(format string, a ...interface{}) error {
	return logf(2, FatalLevel, "", format, a...)
}

func VLogf(verbosity int, format string, a ...interface{}) error {
	return logf(2, LogLevel(-verbosity), "", format, a...)
}

func InfoTf(tag, format string, a ...interface{}) error {
	return logf(2, InfoLevel, tag, format, a...)
}

func WarnTf(tag, format string, a ...interface{}) error {
	return logf(2, WarningLevel, tag, format, a...)
}

func ErrorTf(tag, format string, a ...interface{}) error {
	return logf(2, ErrorLevel, tag, format, a...)
}

func FatalTf(tag, format string, a ...interface{}) error {
	return logf(2, FatalLevel, tag, format, a...)
}

func VLogTf(verbosity int, tag, format string, a ...interface{}) error {
	return logf(2, LogLevel(-verbosity), tag, format, a...)
}

func ToErrMsgTooLong(e error) *ErrMsgTooLong {
	if err, ok := e.(ErrMsgTooLong); ok {
		return &err
	} else {
		return nil
	}
}
