package config

import (
	"net"
	"os"
	"strings"

	ftsService "bsm/full/module/base/fts/service"
	mgtService "bsm/full/module/base/mgt/service"
	passportService "bsm/full/module/base/passport/service"
	senderService "bsm/full/module/base/sender/service"
	walletService "bsm/full/module/finance/wallet/service"
	"git.apinb.com/bsm-sdk/core/conf"
)

type SrvConfig struct {
	conf.Base    `yaml:",inline"`
	Databases    *conf.DBConf            `yaml:"Databases"`
	MicroService *conf.MicroServiceConf  `yaml:"MicroService"`
	Rpc          map[string]conf.RpcConf `yaml:"Rpc"`
	Apm          *conf.ApmConf           `yaml:"APM"`
	Etcd         *conf.EtcdConf          `yaml:"Etcd"`
	Services     []string                `yaml:"Services"`
	Fts          *ftsService.Config      `yaml:"Fts"`
	Mgt          *mgtService.Config      `yaml:"Mgt"`
	Passport     *passportService.Config `yaml:"Passport"`
	Sender       *senderService.Config   `yaml:"Sender"`
	Wallet       *walletService.Config   `yaml:"Wallet"`
}

var Spec SrvConfig

func New(serviceKey string) {
	conf.New(serviceKey, &Spec)
	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)
	assignSharedConfig()
	conf.PrintInfo(Spec.Addr)
}

func assignSharedConfig() {
	if Spec.Fts != nil {
		Spec.Fts.Base, Spec.Fts.Databases, Spec.Fts.Rpc, Spec.Fts.Apm, Spec.Fts.Etcd = Spec.Base, Spec.Databases, Spec.Rpc, Spec.Apm, Spec.Etcd
	}
	if Spec.Mgt != nil {
		Spec.Mgt.Base, Spec.Mgt.Databases, Spec.Mgt.Rpc, Spec.Mgt.Apm, Spec.Mgt.Etcd = Spec.Base, Spec.Databases, Spec.Rpc, Spec.Apm, Spec.Etcd
	}
	if Spec.Passport != nil {
		Spec.Passport.Base, Spec.Passport.Databases, Spec.Passport.MicroService, Spec.Passport.Rpc, Spec.Passport.Apm, Spec.Passport.Etcd = Spec.Base, Spec.Databases, Spec.MicroService, Spec.Rpc, Spec.Apm, Spec.Etcd
	}
	if Spec.Sender != nil {
		Spec.Sender.Base, Spec.Sender.Databases, Spec.Sender.MicroService, Spec.Sender.Rpc, Spec.Sender.Apm, Spec.Sender.Etcd = Spec.Base, Spec.Databases, Spec.MicroService, Spec.Rpc, Spec.Apm, Spec.Etcd
	}
	if Spec.Wallet != nil {
		Spec.Wallet.Base, Spec.Wallet.Databases, Spec.Wallet.MicroService, Spec.Wallet.Rpc, Spec.Wallet.Apm, Spec.Wallet.Etcd = Spec.Base, Spec.Databases, Spec.MicroService, Spec.Rpc, Spec.Apm, Spec.Etcd
	}
}

func Enabled(name string) bool {
	if raw := strings.TrimSpace(os.Getenv("BSM_SERVICES")); raw != "" {
		for _, selected := range strings.Split(raw, ",") {
			if strings.EqualFold(strings.TrimSpace(selected), name) || strings.EqualFold(strings.TrimSpace(selected), "all") {
				return true
			}
		}
		return false
	}
	for _, service := range Spec.Services {
		if strings.EqualFold(strings.TrimSpace(service), name) || strings.EqualFold(strings.TrimSpace(service), "all") {
			return true
		}
	}
	return false
}
