package application

import (
	"encoding/json"
	"git.sxidc.com/go-framework/baize/framework/core/infrastructure"
	"git.sxidc.com/go-tools/utils/fileutils"
	"github.com/pkg/errors"
	"gopkg.in/yaml.v3"
	"os"
)

type Config struct {
	ApiConfig            `json:"api" yaml:"api"`
	InfrastructureConfig `json:"infrastructure" yaml:"infrastructure"`
	*MqttApiConfig       `json:"mqtt_api" yaml:"mqtt_api"`
}

type ApiConfig struct {
	UrlPrefix    string   `json:"url_prefix" yaml:"url_prefix"`
	Port         string   `json:"port" yaml:"port"`
	LogSkipPaths []string `json:"log_skip_paths" yaml:"log_skip_paths"`
}

type InfrastructureConfig struct {
	Database     infrastructure.DatabaseConfig     `json:"database" yaml:"database"`
	Cache        infrastructure.CacheConfig        `json:"cache" yaml:"cache"`
	MessageQueue infrastructure.MessageQueueConfig `json:"message_queue" yaml:"message_queue"`
}

type MqttApiConfig struct {
	TopicPrefix  string     `json:"topic_prefix" yaml:"topic_prefix"`
	LogSkipPaths []string   `json:"log_skip_paths" yaml:"log_skip_paths"`
	MqttConfig   MqttConfig `json:"mqtt_config" yaml:"mqtt_config"`
}

type MqttConfig struct {
	UserName        string `json:"username" yaml:"username"`
	Password        string `json:"password" yaml:"password"`
	Address         string `json:"address" yaml:"address"`
	ClientID        string `json:"client_id" yaml:"client_id"`
	KeepAliveSec    int64  `json:"keep_alive_sec" yaml:"keep_alive_sec"`
	PingTimeoutSec  int64  `json:"ping_timeout_sec" yaml:"ping_timeout_sec"`
	WriteTimeoutSec int64  `json:"write_timeout_sec" yaml:"write_timeout_sec"`
}

func LoadFromJsonFile(jsonFilePath string) (Config, error) {
	if !fileutils.PathExists(jsonFilePath) {
		return Config{}, errors.New("配置文件不存在")
	}

	jsonBytes, err := os.ReadFile(jsonFilePath)
	if err != nil {
		return Config{}, err
	}

	return loadFromJson(jsonBytes)
}

func LoadFromYamlFile(yamlFilePath string) (Config, error) {
	if !fileutils.PathExists(yamlFilePath) {
		return Config{}, errors.New("配置文件不存在")
	}

	yamlBytes, err := os.ReadFile(yamlFilePath)
	if err != nil {
		return Config{}, err
	}

	return loadFromYaml(yamlBytes)
}

func LoadFromJson(jsonStr string) (Config, error) {
	return loadFromJson([]byte(jsonStr))
}

func LoadFromYaml(yamlStr string) (Config, error) {
	return loadFromYaml([]byte(yamlStr))
}

func loadFromJson(jsonBytes []byte) (Config, error) {
	conf := new(Config)
	err := json.Unmarshal(jsonBytes, conf)
	if err != nil {
		return Config{}, errors.New(err.Error())
	}

	return *conf, nil
}

func loadFromYaml(yamlBytes []byte) (Config, error) {
	conf := new(Config)
	err := yaml.Unmarshal(yamlBytes, conf)
	if err != nil {
		return Config{}, errors.New(err.Error())
	}

	return *conf, nil
}