package log

import (
	"fmt"
	"path/filepath"

	"../utils"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

//NewLogger 创建一个uber logger
//
func NewLogger(isFile bool, logPath string, level zapcore.Level) *Logger {
	if isFile {
		if logPath == "" {
			logPath = "./log_file"
		}

		err := utils.CreateDirAll(logPath)
		if err != nil {
			panic(err)
		}
	}

	cfgStdout := zap.NewProductionConfig()
	cfgStdout.Level = zap.NewAtomicLevelAt(level)
	cfgStdout.Encoding = "console"
	if isFile {
		cfgStdout.OutputPaths = []string{filepath.Join(logPath, "stdout.log")}
		cfgStdout.ErrorOutputPaths = []string{filepath.Join(logPath, "internalOut.log")}
	} else {
		cfgStdout.OutputPaths = []string{"stdout"}
		cfgStdout.ErrorOutputPaths = []string{"stderr"}
	}

	cfgStdout.EncoderConfig = zap.NewProductionEncoderConfig()
	cfgStdout.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	lStdout, err := cfgStdout.Build()
	if err != nil {
		panic(fmt.Sprintf("init stdout logger error: %s", err.Error()))
	}

	cfgStderr := zap.NewProductionConfig()
	cfgStderr.Level = zap.NewAtomicLevelAt(level)
	cfgStderr.Encoding = "console"
	if isFile {
		cfgStderr.OutputPaths = []string{filepath.Join(logPath, "stderr.log")}
		cfgStderr.ErrorOutputPaths = []string{filepath.Join(logPath, "internalErr.log")}
	} else {
		cfgStderr.OutputPaths = []string{"stderr"}
		cfgStderr.ErrorOutputPaths = []string{"stderr"}
	}
	cfgStderr.EncoderConfig = zap.NewProductionEncoderConfig()
	cfgStderr.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	lStderr, err := cfgStderr.Build()
	if err != nil {
		panic(fmt.Sprintf("init stderr logger error: %s", err.Error()))
	}

	return &Logger{rawStdoutLog: lStdout, rawStderrLog: lStderr}
}

type Logger struct {
	rawStdoutLog *zap.Logger
	rawStderrLog *zap.Logger
}

func (l *Logger) Debug(msg string, fields ...zapcore.Field) {
	l.rawStdoutLog.Debug(msg, fields...)
}

func (l *Logger) Info(msg string, fields ...zapcore.Field) {
	l.rawStdoutLog.Info(msg, fields...)
}

func (l *Logger) Warn(msg string, fields ...zapcore.Field) {
	l.rawStdoutLog.Warn(msg, fields...)
}

func (l *Logger) Error(msg string, fields ...zapcore.Field) {
	l.rawStderrLog.Error(msg, fields...)
}

func (l *Logger) Panic(msg string, fields ...zapcore.Field) {
	l.rawStderrLog.Panic(msg, fields...)
}

func (l *Logger) Fatal(msg string, fields ...zapcore.Field) {
	l.rawStderrLog.Fatal(msg, fields...)
}

func (l *Logger) CustomFlush() {
	l.rawStdoutLog.Sync()
	l.rawStderrLog.Sync()
}

func SetDefaultLog(l *Logger) {
	defaultLog = l
}
func GetDefaultLog() *Logger {
	return defaultLog
}

var defaultLog *Logger

func Debug(msg string, fields ...zapcore.Field) {
	defaultLog.rawStdoutLog.Debug(msg, fields...)
}

func Info(msg string, fields ...zapcore.Field) {
	defaultLog.rawStdoutLog.Info(msg, fields...)
}

func Warn(msg string, fields ...zapcore.Field) {
	defaultLog.rawStdoutLog.Warn(msg, fields...)
}

func Error(msg string, fields ...zapcore.Field) {
	defaultLog.rawStderrLog.Error(msg, fields...)
}

func Panic(msg string, fields ...zapcore.Field) {
	defaultLog.rawStderrLog.Panic(msg, fields...)
}

func Fatal(msg string, fields ...zapcore.Field) {
	defaultLog.rawStderrLog.Fatal(msg, fields...)
}

func CustomFlush() {
	defaultLog.rawStdoutLog.Sync()
	defaultLog.rawStderrLog.Sync()
}
