// Package config 提供CMS服务的配置管理功能
// 负责加载和验证服务配置参数，包括数据库、缓存、微服务等配置
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 CMS服务配置结构体
// 继承基础配置，并扩展数据库、微服务、网关等特定配置
type SrvConfig struct {
	conf.Base    `yaml:",inline"`        // 基础配置（服务名、端口、缓存等）
	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"`          // APM监控配置
	Etcd         *conf.EtcdConf          `yaml:"Etcd"`         // Etcd配置
}

// New 初始化配置
// 根据服务标识符加载配置文件，验证配置参数的有效性
// 参数:
//   - srvKey: 服务标识符，用于确定配置文件路径
func New(srvKey string) {
	// 加载配置文件，将配置数据解析到Spec结构体中
	conf.New(srvKey, &Spec)

	// 验证和修正端口配置，如果端口不合法则分配随机端口
	Spec.Port = conf.CheckPort(Spec.Port)

	// 验证和修正IP地址配置，确保IP地址有效
	Spec.BindIP = conf.CheckIP(Spec.BindIP)

	// 组合IP和端口，生成完整的服务地址
	Spec.Addr = net.JoinHostPort(Spec.BindIP, Spec.Port)

	// 验证关键配置项不能为空
	// 服务名称和缓存配置是必需的
	conf.NotNil(Spec.Service, Spec.Cache)

	// 初始化JWT加密密钥，用于身份验证
	encipher.New(env.Runtime.JwtSecretKey)

	// 打印服务启动信息，包括监听地址
	conf.PrintInfo(Spec.Addr)
}
