package config

import (
	"fmt"
	"os"

	"git.hpds.cc/Component/logging"
	consulApi "github.com/hashicorp/consul/api"
	_ "github.com/spf13/viper/remote"
	yaml "gopkg.in/yaml.v3"
)

type DataMinioConfig struct {
	Name    string       `yaml:"name" json:"name" toml:"name"`
	Mode    string       `yaml:"mode" json:"mode"`
	Consul  ConsulConfig `yaml:"consul,omitempty"`
	Db      DbConfig     `yaml:"db"`
	Logging LogOptions   `yaml:"logging"`
	Minio   MinioConfig  `yaml:"minio"`
	Node    HpdsNode     `yaml:"node,omitempty"`
	Funcs   []FuncConfig `yaml:"functions,omitempty"`
}

type ConsulConfig struct {
	Host       string   `yaml:"host,omitempty"`
	Port       int      `yaml:"port,omitempty"`
	Interval   int      `yaml:"interval,omitempty"`
	Timeout    int      `yaml:"timeout,omitempty"`
	Deregister int      `yaml:"deregister,omitempty"`
	Tags       []string `yaml:"tags,omitempty"`
}
type DbConfig struct {
	Conn      string `yaml:"conn"`
	DriveName string `yaml:"drive_name"`
}

type LogOptions struct {
	Path            string `yaml:"path" json:"path" toml:"path"`                                  // 文件保存地方
	Prefix          string `yaml:"prefix" json:"prefix" toml:"prefix"`                            // 日志文件前缀
	ErrorFileSuffix string `yaml:"errorFileSuffix" json:"errorFileSuffix" toml:"errorFileSuffix"` // error日志文件后缀
	WarnFileSuffix  string `yaml:"warnFileSuffix" json:"warnFileSuffix" toml:"warnFileSuffix"`    // warn日志文件后缀
	InfoFileSuffix  string `yaml:"infoFileSuffix" json:"infoFileSuffix" toml:"infoFileSuffix"`    // info日志文件后缀
	DebugFileSuffix string `yaml:"debugFileSuffix" json:"debugFileSuffix" toml:"debugFileSuffix"` // debug日志文件后缀
	Level           string `yaml:"level" json:"level" toml:"level"`                               // 日志等级
	MaxSize         int    `yaml:"maxSize" json:"maxSize" toml:"maxSize"`                         // 日志文件大小（M）
	MaxBackups      int    `yaml:"maxBackups" json:"maxBackups" toml:"maxBackups"`                // 最多存在多少个切片文件
	MaxAge          int    `yaml:"maxAge" json:"maxAge" toml:"maxAge"`                            // 保存的最大天数
	Development     bool   `yaml:"development" json:"development" toml:"development"`             // 是否是开发模式
}

type MinioConfig struct {
	Protocol        string `yaml:"protocol"` //http or https
	Endpoint        string `yaml:"endpoint"`
	AccessKeyId     string `yaml:"accessKeyId"`
	SecretAccessKey string `yaml:"secretAccessKey"`
	Bucket          string `yaml:"bucket"`
}

type HpdsNode struct {
	Host  string `yaml:"host"`
	Port  int    `yaml:"port"`
	Token string `yaml:"token,omitempty"`
}

type FuncConfig struct {
	Name    string `yaml:"name"`
	DataTag uint8  `yaml:"dataTag"`
	MqType  uint   `yaml:"mqType"` //消息类型， 发布，1；订阅；2
}

func ParseConfigByFile(path string) (cfg *DataMinioConfig, err error) {
	buffer, err := os.ReadFile(path)
	if err != nil {
		return nil, err
	}
	return load(buffer)
}

func load(buf []byte) (cfg *DataMinioConfig, err error) {

	cfg = new(DataMinioConfig)
	cfg.Funcs = make([]FuncConfig, 0)
	err = yaml.Unmarshal(buf, cfg)
	return
}

func UpdateLocalConfig(cfg *DataMinioConfig, fn string) error {
	data, err := yaml.Marshal(cfg)
	if err != nil {
		return err
	}
	err = os.WriteFile(fn, data, 0600)
	return err
}

func UpdateRemoteConfig(cfg *DataMinioConfig) error {
	consulClient, err := consulApi.NewClient(&consulApi.Config{Address: fmt.Sprintf("%s:%d", cfg.Consul.Host, cfg.Consul.Port)})
	if err != nil {
		return err
	}
	val, err := yaml.Marshal(cfg)
	if err != nil {
		return err
	}
	p := &consulApi.KVPair{Key: fmt.Sprintf("hpds-pavement/hpds_data_minio/%s/%s", cfg.Mode, cfg.Name), Value: val}
	if _, err = consulClient.KV().Put(p, nil); err != nil {
		return err
	}
	return nil
}

func GetRemoteConfig(remoteAddr, path string) (cfg *DataMinioConfig, err error) {
	consulClient, err := consulApi.NewClient(&consulApi.Config{Address: remoteAddr})
	if err != nil {
		return nil, err
	}
	kv, _, err := consulClient.KV().Get(path, nil)
	if err != nil {
		return nil, err
	}
	return load(kv.Value)
}

func LoadLoggerConfig(opt LogOptions) *logging.Logger {
	return logging.NewLogger(
		logging.SetPath(opt.Path),
		logging.SetPrefix(opt.Prefix),
		logging.SetDevelopment(opt.Development),
		logging.SetDebugFileSuffix(opt.DebugFileSuffix),
		logging.SetWarnFileSuffix(opt.WarnFileSuffix),
		logging.SetErrorFileSuffix(opt.ErrorFileSuffix),
		logging.SetInfoFileSuffix(opt.InfoFileSuffix),
		logging.SetMaxAge(opt.MaxAge),
		logging.SetMaxBackups(opt.MaxBackups),
		logging.SetMaxSize(opt.MaxSize),
		logging.SetLevel(logging.LogLevel["debug"]),
	)
}
