package infra

import (
	"os"

	"github.com/imdario/mergo"
	clinicCfg "github.com/pingcap-inc/clinic/pkg/config"
	"github.com/pingcap/errors"
	"go.uber.org/zap/zapcore"
	"gopkg.in/yaml.v3"
)

type Config struct {
	ServerConfig    ServerConfig          `yaml:"server"`
	DBaasConfig     clinicCfg.DBaasConfig `yaml:"dbaas-config"`
	ClinicDBConfig  clinicCfg.DBConfig    `yaml:"clinic-db"`
	ChaosDBConfig   clinicCfg.DBConfig    `yaml:"chaos-db"`
	ChaosGrpcTarget string                `yaml:"chaos-grpc-target"`
	LogLevel        zapcore.Level         `yaml:"log-level"`
}

type ServerConfig struct {
	Addr string `yaml:"addr"`
}

func NewConfig(configPath, secretConfigPath string) (*Config, error) {
	cfg := Config{}
	bytes, err := os.ReadFile(configPath)
	if err != nil {
		return nil, errors.Annotate(err, "failed to read config")
	}

	err = yaml.Unmarshal(bytes, &cfg)
	if err != nil {
		return nil, errors.Annotate(err, "failed to read unmarshal config")
	}

	if secretConfigPath != "" {
		secretCfg := Config{}
		bytes, err := os.ReadFile(secretConfigPath)
		if err != nil {
			return nil, errors.Annotate(err, "failed to read secret config")
		}

		err = yaml.Unmarshal(bytes, &secretCfg)
		if err != nil {
			return nil, errors.Annotate(err, "failed to unmarshal secret config")
		}

		if err = mergo.Merge(&cfg, &secretCfg, mergo.WithOverride); err != nil {
			return nil, errors.Annotate(err, "failed to merge secret config")
		}
	}

	return &cfg, nil
}
