package config

import (
	"net"

	"git.apinb.com/bsm-sdk/core/conf"
	"git.apinb.com/bsm-sdk/core/crypto/encipher"
	"git.apinb.com/bsm-sdk/core/env"
)

var (
	// Spec 全局配置实例，包含所有服务配置信息
	Spec SrvConfig
)

// SrvConfig 服务配置结构体，包含所有必要的配置项
type SrvConfig struct {
	conf.Base    `yaml:",inline"`        // 基础配置（端口、IP等）
	Databases    *conf.DBConf            `yaml:"Databases"`    // 数据库配置
	MicroService *conf.MicroServiceConf  `yaml:"MicroService"` // 微服务配置
	Rpc          map[string]conf.RpcConf `yaml:"Rpc"`          // RPC服务配置
	Gateway      *conf.GatewayConf       `yaml:"Gateway"`      // HTTP网关配置
	Apm          *conf.ApmConf           `yaml:"APM"`          // 应用性能监控配置
	Etcd         *conf.EtcdConf          `yaml:"Etcd"`         // Etcd配置
	SMS          map[string]*SmsConf     `yaml:"SMS"`          // 短信服务配置
	SMTP         map[string]*SmtpConf    `yaml:"SMTP"`         // 邮件服务配置
	Code         *codeConf               `yaml:"Code"`         // 验证码配置
}

// SmtpConf SMTP邮件服务配置
type SmtpConf struct {
	Endpoint    string `yaml:"Endpoint"`    // SMTP服务器地址
	Port        int    `yaml:"Port"`        // SMTP服务器端口
	Username    string `yaml:"Username"`    // 用户名
	Password    string `yaml:"Password"`    // 密码
	FromAddress string `yaml:"FromAddress"` // 发件人邮箱地址
	FromName    string `yaml:"FromName"`    // 发件人显示名称
}

// SmsConf 短信服务配置
type SmsConf struct {
	Endpoint        string `yaml:"Endpoint"`        // 短信服务端点
	AccessKeyId     string `yaml:"AccessKeyId"`     // 访问密钥ID
	AccessKeySecret string `yaml:"AccessKeySecret"` // 访问密钥Secret
	Region          string `yaml:"Region"`          // 服务区域
}

// codeConf 验证码相关配置
type codeConf struct {
	Length          int64    `yaml:"Length"`          // 验证码长度
	Expire          int      `yaml:"Expire"`          // 验证码过期时间（秒）
	MaxSentLimit    int      `yaml:"MaxSentLimit"`    // 最大发送次数限制
	GenerateCode    bool     `yaml:"GenerateCode"`    // 是否生成验证码
	CokeyKey        string   `yaml:"CokeyKey"`        // 验证码密钥
	BlackListFilter []string `yaml:"BlackListFilter"` // 黑名单过滤器
}

// New 初始化配置文件并进行必要的校验
// srvKey: 服务标识符，用于加载对应的配置文件
func New(srvKey string) {
	// 初始化配置，创建一个新的配置实例，用于服务配置
	conf.New(srvKey, &Spec)

	// 配置校验：服务IP和端口，如果端口不合规则随机分配端口
	Spec.Port = conf.CheckPort(Spec.Port)
	Spec.BindIP = conf.CheckIP(Spec.BindIP)
	Spec.Addr = net.JoinHostPort(Spec.BindIP, Spec.Port)

	// 配置校验：服务名称地址及监听地址不能为空
	conf.NotNil(Spec.Service, Spec.Cache)

	// 初始化JWT加密密钥
	encipher.New(env.Runtime.JwtSecretKey)

	// 打印服务启动信息
	conf.PrintInfo(Spec.Addr)
}
