package config

import (
	"fmt"
	"os"
	"strings"

	"be.ems/lib/global"
	"be.ems/lib/log"

	"gopkg.in/yaml.v3"
)

type DbConfig struct {
	Type     string `yaml:"type"`
	User     string `yaml:"user"`
	Password string `yaml:"password"`
	Host     string `yaml:"host"`
	Port     string `yaml:"port"`
	Name     string `yaml:"name"`
	Backup   string `yaml:"backup"`
}

// Yaml struct of config
type YamlConfig struct {
	Logger struct {
		File     string `yaml:"file"`
		Level    string `yaml:"level"`
		Duration int    `yaml:"duration"`
		Count    int    `yaml:"count"`
	} `yaml:"logger"`

	Rest []struct {
		IPv4           string `yaml:"ipv4"`
		IPv6           string `yaml:"ipv6"`
		Port           uint16 `yaml:"port"`
		Scheme         string `yaml:"scheme"`
		ClientAuthType int    `yaml:"clientAuthType"`
		CaFile         string `yaml:"caFile"`
		CertFile       string `yaml:"certFile"`
		KeyFile        string `yaml:"keyFile"`
	} `yaml:"rest"`

	WebServer struct {
		Enabled bool   `yaml:"enabled"`
		RootDir string `yaml:"rootDir"`
		Listen  []struct {
			Addr           string `yaml:"addr"`
			Scheme         string `yaml:"scheme"`
			ClientAuthType int    `yaml:"clientAuthType"`
			CaFile         string `yaml:"caFile"`
			CertFile       string `yaml:"certFile"`
			KeyFile        string `yaml:"keyFile"`
		} `yaml:"listen"`
	} `yaml:"webServer"`

	Database DbConfig `yaml:"database"`

	OMC struct {
		UriPrefix        string `yaml:"uriPrefix"`
		NeType           string `yaml:"neType"`
		NeId             string `yaml:"neId"`
		RmUID            string `yaml:"rmUID"`
		NeName           string `yaml:"neName"`
		Province         string `yaml:"province"`
		Vendor           string `yaml:"vendor"`
		Dn               string `yaml:"dn"`
		Chk2Ne           bool   `yaml:"chk2ne"`
		Sn               string `yaml:"sn"`
		CheckSign        bool   `yaml:"checksign"`
		RootDir          string `yaml:"rootDir"`
		BinDir           string `yaml:"binDir"`
		Backup           string `yaml:"backup"`
		Upload           string `yaml:"upload"`
		FrontUpload      string `yaml:"frontUpload"`
		FrontTraceDir    string `yaml:"frontTraceDir"`
		Software         string `yaml:"software"`
		License          string `yaml:"license"`
		GtpUri           string `yaml:"gtpUri"`
		CheckContentType bool   `yaml:"checkContentType"`
		TestMode         bool   `yaml:"testMode"`
		RBACMode         bool   `yaml:"rbacMode"`
		RunDir           string `yaml:"runDir"`
		CmdTimeout       int    `yaml:"cmdTimeout"`
	} `yaml:"omc"`

	Alarm struct {
		ForwardAlarm bool `yaml:"forwardAlarm"`
		Email        struct {
			Smtp          string `yaml:"smtp"`
			Port          uint16 `yaml:"port"`
			User          string `yaml:"user"`
			Password      string `yaml:"password"`
			TlsSkipVerify bool   `yaml:"tlsSkipVerify"`
		} `yaml:"email"`
		SMS struct {
			ApiURL          string `yaml:"apiURL"`
			AccessKeyID     string `yaml:"AccessKeyID"`
			AccessKeySecret string `yaml:"accessKeySecret"`
			SignName        string `yaml:"signName"`
			TemplateCode    string `yaml:"templateCode"`
		} `yaml:"sms"`
		SMSC struct {
			Addr     string `yaml:"addr"`
			UserName string `yaml:"userName"`
			Password string `yaml:"password"`
		} `yaml:"smsc"`
	} `yaml:"alarm"`

	MML struct {
		Port     int    `yaml:"port"`
		Port2    int    `yaml:"port2"`
		Sleep    int64  `yaml:"sleep"`
		DeadLine int64  `yaml:"deadLine"`
		User     string `yaml:"user"`
		Password string `ymal:"password"`
		MmlHome  string `yaml:"mmlHome"`
		Upload   string `yaml:"upload"`
	} `yaml:"mml"`

	NE struct {
		Addr           string `yaml:"addr"`
		Port           uint16 `yaml:"port"`
		User           string `yaml:"user"`
		EtcDir         string `yaml:"etcdir"`
		BinDir         string `yaml:"bindir"`
		OmcDir         string `yaml:"omcdir"`
		ScpDir         string `yaml:"scpdir"`
		LicenseDir     string `yaml:"licensedir"`
		EtcListIMS     string `yaml:"etcListIMS"`
		EtcListDefault string `yaml:"etcListDefault"`
		DpkgOverwrite  bool   `yaml:"dpkgOverwrite"`
		DpkgTimeout    int    `yaml:"dpkgTimeout"`
	} `yaml:"ne"`

	Auth struct {
		Crypt      string `yaml:"crypt"`
		Token      bool   `yaml:"token"`
		Expires    uint32 `yaml:"expires"`
		Session    string `yaml:"session"`
		PublicKey  string `yaml:"publicKey"`
		PrivateKey string `yaml:"privateKey"`
	} `yaml:"auth"`

	Params struct {
		RmUIDMaxNum   int    `yaml:"rmuidmaxnum"`
		AlarmIDMaxNum int    `yaml:"alarmidmaxnum"`
		PmIDMaxNum    int    `yaml:"pmidmaxnum"`
		SubIDMaxNum   int    `yaml:"subidmaxnum"`
		UriMaxLen     int    `yaml:"urimaxlen"`
		RmUIDRegexp   string `yaml:"rmuidregexp"`
	} `yaml:"params"`

	TestConfig struct {
		Enabled bool   `yaml:"enabled"`
		File    string `yaml:"file"`
	} `yaml:"testConfig"`
}

type TestDatas struct {
	UDM struct {
		CapUsed        uint32   `yaml:"capUsed"`
		FeatureEnabled []string `yaml:"featureEnabled"`
	} `yaml:"udm"`
	AUSF struct {
		CapUsed        uint32   `yaml:"capUsed"`
		FeatureEnabled []string `yaml:"featureEnabled"`
	} `yaml:"ausf"`
	AMF struct {
		CapUsed        uint32   `yaml:"capUsed"`
		FeatureEnabled []string `yaml:"featureEnabled"`
	} `yaml:"amf"`
	SMF struct {
		CapUsed        uint32   `yaml:"capUsed"`
		FeatureEnabled []string `yaml:"featureEnabled"`
	} `yaml:"smf"`
	UPF struct {
		CapUsed        uint32   `yaml:"capUsed"`
		FeatureEnabled []string `yaml:"featureEnabled"`
	} `yaml:"upf"`
}

type NeTestData struct {
	CapUsed        uint32   `yaml:"capUsed"`
	FeatureEnabled []string `yaml:"featureEnabled"`
}
type TestDataMap struct {
	NeTestDatas []map[string]NeTestData
}

var yamlConfig YamlConfig

func ReadConfig(configFile string) {
	yamlFile, err := os.ReadFile(configFile)
	if err != nil {
		fmt.Println("Read yaml config file error:", err)
		os.Exit(2)
	}
	//	fmt.Println("yamlfile:", string(yamlFile))

	err = yaml.Unmarshal(yamlFile, &yamlConfig)
	if err != nil {
		fmt.Println("Unmarshal error:", err)
		os.Exit(3)
	}
}

func WriteYamlConfig(newConfigData YamlConfig, configFile string) {
	// 将配置转换回YAML数据
	newYamlData, err := yaml.Marshal(&newConfigData)
	if err != nil {
		log.Errorf("Failed to marshal YAML: %v", err)
	}

	// 将新的YAML数据写入文件
	err = os.WriteFile(configFile, newYamlData, 0644)
	if err != nil {
		log.Errorf("Failed to write YAML file: %v", err)
	}
}

var mapYaml map[string]interface{}

func ReadParamConfig(fileName string) *map[string]interface{} {
	file, err := os.ReadFile(fileName)
	if err != nil {
		fmt.Println("Read yaml file error:", err)
	}

	mapYaml = make(map[string]interface{})

	err = yaml.Unmarshal(file, &mapYaml)
	if err != nil {
		fmt.Printf("yaml.Unmarshal: %v when to struct", err)
	}
	//	fmt.Println("mapYaml:", mapYaml)

	return &mapYaml
}

func GetYamlConfig() *YamlConfig {
	return &yamlConfig
}

func GetAuthFromConfig() interface{} {
	return yamlConfig.Auth
}

func GetExpiresFromConfig() uint32 {
	return yamlConfig.Auth.Expires
}

func GetRmUIDFromConfig() string {
	return yamlConfig.OMC.RmUID
}

func GetRmUIDRegexpFromConfig() string {
	return yamlConfig.Params.RmUIDRegexp
}

func GetRmUIDMaxNumFromConfig() int {
	return yamlConfig.Params.RmUIDMaxNum
}

func GetAlarmIDMaxNumFromConfig() int {
	return yamlConfig.Params.AlarmIDMaxNum
}

func GetPmIDMaxNumFromConfig() int {
	return yamlConfig.Params.PmIDMaxNum
}

func GetSubIDMaxNumFromConfig() int {
	return yamlConfig.Params.SubIDMaxNum
}

func GetUriMaxLenFromConfig() int {
	return yamlConfig.Params.UriMaxLen
}

func GetLogLevel() log.LogLevel {
	var logLevel log.LogLevel
	switch strings.ToLower(yamlConfig.Logger.Level) {
	case "trace":
		logLevel = log.LOG_TRACE
	case "info":
		logLevel = log.LOG_INFO
	case "debug":
		logLevel = log.LOG_DEBUG
	case "warn":
		logLevel = log.LOG_WARN
	case "error":
		logLevel = log.LOG_ERROR
	case "fatal":
		logLevel = log.LOG_FATAL
	case "off":
		logLevel = log.LOG_OFF
	default:
		logLevel = log.LOG_DEBUG
	}
	return logLevel
}

var (
	DefaultUriPrefix string = "/api/rest"
	UriPrefix        string = "/omc/rest"
	//TestDataUDM  []map[string]interface{}
	TDatas map[string]NeTestData
)

func ReadTestConfigYaml(pfile string) (ret error) {
	file, err := os.ReadFile(pfile)
	if err != nil {
		return err
	}

	err = yaml.Unmarshal(file, &TDatas)
	if err != nil {
		fmt.Println("Failed to Unmarshal:", err)
		return err
	}

	return nil
}

func GetDefaultUserAgent() string {
	return "OMC-restagent/" + global.Version
}

// const defaultConfigFile = "./etc/restconf.yaml"

// func init() {
// 	cfile := flag.String("c", defaultConfigFile, "config file")
// 	pv := flag.Bool("version", false, "print version")
// 	ph := flag.Bool("help", false, "print help")

// 	//global.BuildTime = "Wed May 31 18:24:04 CST 2023"
// 	//global.GoVer = "go version go1.15.7 linux/arm64"
// 	flag.Parse()
// 	if *pv {
// 		fmt.Printf("OMC restagent version: %s\n%s\n%s\n\n", global.Version, global.BuildTime, global.GoVer)
// 		os.Exit(0)
// 	}
// 	if *ph {
// 		flag.Usage()
// 		os.Exit(0)
// 	}

// 	// 使用viper读取配置
// 	conf.InitConfig(*cfile)

// 	ReadConfig(*cfile)
// 	if GetYamlConfig().OMC.UriPrefix != "" {
// 		UriPrefix = GetYamlConfig().OMC.UriPrefix
// 	}
// 	if GetYamlConfig().TestConfig.Enabled {
// 		ReadTestConfigYaml(GetYamlConfig().TestConfig.File)
// 	}
// }
