//
// Copyright 2019 AT&T Intellectual Property
// Copyright 2019 Nokia
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package logger

import (
	"fmt"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"strings"
	"time"
)

type Logger struct {
	Logger     *zap.Logger
}

// Copied from zap logger
//
// A Level is a logging priority. Higher levels are more important.
type LogLevel int8

const (
	// DebugLevel logs are typically voluminous, and are usually disabled in
	// production.
	DebugLevel LogLevel = iota - 1
	// InfoLevel is the default logging priority.
	InfoLevel
	// WarnLevel logs are more important than Info, but don't need individual
	// human review.
	WarnLevel
	// ErrorLevel logs are high-priority. If an application is running smoothly,
	// it shouldn't generate any error-level logs.
	ErrorLevel
	// DPanicLevel logs are particularly important errors. In development the
	// logger panics after writing the message.
	DPanicLevel
	// PanicLevel logs a message, then panics.
	PanicLevel
	// FatalLevel logs a message, then calls os.Exit(1).
	FatalLevel

	_minLevel = DebugLevel
	_maxLevel = FatalLevel
)

var logLevelTokenToLevel = map[string] LogLevel {
	"debug" : DebugLevel,
	"info": InfoLevel,
	"warn": WarnLevel,
	"error": ErrorLevel,
	"dpanic": DPanicLevel,
	"panic": PanicLevel,
	"fatal": FatalLevel,
}

func LogLevelTokenToLevel(level string) (LogLevel, bool) {
	if level, ok := logLevelTokenToLevel[strings.TrimSpace(strings.ToLower(level))];ok {
		return level, true
	}
	return _maxLevel+1, false
}

func InitLogger(requested LogLevel) (*Logger, error) {
	var logger *zap.Logger
	var err error
	switch requested {
	case DebugLevel:
		logger, err = initLoggerByLevel(zapcore.DebugLevel)
	case InfoLevel:
		logger, err = initLoggerByLevel(zapcore.InfoLevel)
	case WarnLevel:
		logger, err = initLoggerByLevel(zapcore.WarnLevel)
	case ErrorLevel:
		logger, err = initLoggerByLevel(zapcore.ErrorLevel)
	case DPanicLevel:
		logger, err = initLoggerByLevel(zapcore.DPanicLevel)
	case PanicLevel:
		logger, err = initLoggerByLevel(zapcore.PanicLevel)
	case FatalLevel:
		logger, err = initLoggerByLevel(zapcore.FatalLevel)
	default:
		err = fmt.Errorf("Invalid logging Level :%d",requested)
	}
	if err != nil {
		return nil, err
	}
	return &Logger{Logger:logger}, nil

}
func(l *Logger)Sync() error {
	l.Debugf("#logger.Sync - Going to flush buffered log")
	return l.Logger.Sync()
}

func (l *Logger)Infof(formatMsg string, a ...interface{})  {
	if l.InfoEnabled() {
		msg := fmt.Sprintf(formatMsg, a...)
		l.Logger.Info(msg, zap.Any("mdc", l.getTimeStampMdc()))
	}
}

func (l *Logger)Debugf(formatMsg string, a ...interface{})  {
	if l.DebugEnabled(){
		msg := fmt.Sprintf(formatMsg, a...)
		l.Logger.Debug(msg, zap.Any("mdc", l.getTimeStampMdc()))
	}
}

func (l *Logger)Errorf(formatMsg string, a ...interface{})  {
	msg := fmt.Sprintf(formatMsg, a...)
	l.Logger.Error(msg, zap.Any("mdc", l.getTimeStampMdc()))
}

func (l *Logger)Warnf(formatMsg string, a ...interface{})  {
	msg := fmt.Sprintf(formatMsg, a...)
	l.Logger.Warn(msg, zap.Any("mdc", l.getTimeStampMdc()))
}

func (l *Logger) getTimeStampMdc() map[string]string {
	timeStr := time.Now().Format("2006-01-02 15:04:05.000")
	mdc := map[string]string{"time": timeStr}
	return mdc
}

func (l *Logger)InfoEnabled()bool{
	return l.Logger.Core().Enabled(zap.InfoLevel)
}

func (l *Logger)DebugEnabled()bool{
	return l.Logger.Core().Enabled(zap.DebugLevel)
}

func (l *Logger)DPanicf(formatMsg string, a ...interface{})  {
	msg := fmt.Sprintf(formatMsg, a...)
	l.Logger.DPanic(msg, zap.Any("mdc", l.getTimeStampMdc()))
}

func initLoggerByLevel(l zapcore.Level) (*zap.Logger, error) {
	cfg := zap.Config{
		Encoding:         "json",
		Level:            zap.NewAtomicLevelAt(l),
		OutputPaths:      []string{"stdout"},
		ErrorOutputPaths: []string{"stderr"},
		EncoderConfig: zapcore.EncoderConfig{
			MessageKey: "msg",

			LevelKey:    "crit",
			EncodeLevel: zapcore.CapitalLevelEncoder,

			TimeKey:    "ts",
			EncodeTime: epochMillisIntegerTimeEncoder,

			CallerKey: "id",
			EncodeCaller: e2ManagerCallerEncoder,
		},
	}
	return cfg.Build()
}

func e2ManagerCallerEncoder(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) {
	enc.AppendString("E2Manager")
}

func epochMillisIntegerTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
	nanos := t.UnixNano()
	millis := int64(nanos) / int64(time.Millisecond)
	enc.AppendInt64(millis)
}

