package config

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

type Zap struct {
	// 级别 info debug warn error dpanic panic fatal
	Level  string `mapstructure:"level" json:"level" yaml:"level"`
	Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"` // 日志前缀
	// 输出  console: 控制台形式输出日志 json: json格式输出日志
	Format string `mapstructure:"format" json:"format" yaml:"format"`
	// 日志文件夹 存放日志的文件夹,修改即可,不需要手动创建
	Director string `mapstructure:"director" json:"director"  yaml:"director"`
	// 编码级 LowercaseLevelEncoder:小写  LowercaseColorLevelEncoder:小写带颜色 CapitalColorLevelEncoder: 大写带颜色 CapitalLevelEncoder: 大写
	EncodeLevel   string `mapstructure:"encode-level" json:"encode-level" yaml:"encode-level"`
	StacktraceKey string `mapstructure:"stacktrace-key" json:"stacktrace-key" yaml:"stacktrace-key"` // 栈名
	ShowLine      bool   `mapstructure:"show-line" json:"show-line" yaml:"show-line"`                // 显示行 显示行号, 默认为true,不建议修改
	LogInConsole  bool   `mapstructure:"log-in-console" json:"log-in-console" yaml:"log-in-console"` // 输出控制台
	ConsoleInLog  bool   `mapstructure:"console-in-log" json:"console-in-log" yaml:"console-in-log"` // 输出控制台
	RetentionDay  int    `mapstructure:"retention-day" json:"retention-day" yaml:"retention-day"`    // 日志保留天数
	MaxSize       string `mapstructure:"max-size" json:"maxSize"`                                    // 单个日志文件最大大小  1kb, 1mb 1g

	Compress      bool   `mapstructure:"compress" json:"compress"`             // 切割后是否压缩旧文件(gzip)
	CompressLevel int    `mapstructure:"compress-level" json:"compress-level"` // gzip 压缩等级（1-9）
	CheckInterval string `mapstructure:"check-interval" json:"check-interval"` // 定时检查切割的时间间隔 定时检查间隔（如"30s"、"1m"，默认30秒）
}

// Levels 根据字符串转化为 zapcore.Levels
func (c *Zap) Levels() []zapcore.Level {
	levels := make([]zapcore.Level, 0, 7)
	level, err := zapcore.ParseLevel(c.Level)
	if err != nil {
		level = zapcore.DebugLevel
	}
	for ; level <= zapcore.FatalLevel; level++ {
		levels = append(levels, level)
	}
	return levels
}

func (c *Zap) Encoder() zapcore.Encoder {
	config := zapcore.EncoderConfig{
		TimeKey:       "time",
		NameKey:       "name",
		LevelKey:      "level",
		CallerKey:     "caller",
		MessageKey:    "message",
		StacktraceKey: c.StacktraceKey,
		LineEnding:    zapcore.DefaultLineEnding,
		EncodeTime: func(t time.Time, encoder zapcore.PrimitiveArrayEncoder) {
			encoder.AppendString(c.Prefix + t.Format("2006-01-02 15:04:05.000"))
		},
		EncodeLevel:    c.LevelEncoder(),
		EncodeCaller:   zapcore.FullCallerEncoder,
		EncodeDuration: zapcore.SecondsDurationEncoder,
	}
	if c.Format == "json" {
		return zapcore.NewJSONEncoder(config)
	}
	return zapcore.NewConsoleEncoder(config)

}

// LevelEncoder 根据 EncodeLevel 返回 zapcore.LevelEncoder
// Author [SliverHorn](https://github.com/SliverHorn)
func (c *Zap) LevelEncoder() zapcore.LevelEncoder {
	switch {
	case c.EncodeLevel == "LowercaseLevelEncoder": // 小写编码器(默认)
		return zapcore.LowercaseLevelEncoder
	case c.EncodeLevel == "LowercaseColorLevelEncoder": // 小写编码器带颜色
		return zapcore.LowercaseColorLevelEncoder
	case c.EncodeLevel == "CapitalLevelEncoder": // 大写编码器
		return zapcore.CapitalLevelEncoder
	case c.EncodeLevel == "CapitalColorLevelEncoder": // 大写编码器带颜色
		return zapcore.CapitalColorLevelEncoder
	default:
		return zapcore.LowercaseLevelEncoder
	}
}

// 新增自定义调用者编码器方法，用于输出相对路径
func (c *Zap) CallerEncoder() zapcore.CallerEncoder {
	return func(caller zapcore.EntryCaller, encoder zapcore.PrimitiveArrayEncoder) {
		// 获取项目根目录（根据实际项目结构调整，这里假设根目录是模块名，如 "your/project/root"）
		// 注意：需要替换为你的项目实际根目录（可以通过 go.mod 中的模块名确定）
		projectRoot := "lampserver-10"

		// 截取相对路径（从项目根目录开始）
		fullPath := caller.String()
		relativePath := fullPath
		if len(fullPath) >= len(projectRoot) {
			relativePath = fullPath[len(projectRoot)+1:] // +1 是为了去掉根目录后的斜杠
		}

		encoder.AppendString(relativePath)
	}
}
