package model

import (
	"encoding/json"
	"os"

	"git.pyer.club/kingecg/gohttpd/utils"
	"git.pyer.club/kingecg/gologger"
)

// HealthCheckConfig 定义健康检查配置
type HealthCheckConfig struct {
	Interval string `json:"interval,omitempty"` // 检查间隔时间
	Timeout  string `json:"timeout,omitempty"`  // 单次检查超时时间
	Retries  int    `json:"retries,omitempty"` // 健康检查失败重试次数
}

// HttpPath 定义HTTP路径配置
type HttpPath struct {
	Path       string   `json:"path"`
	Root       string   `json:"root"`
	Default    string   `json:"default"`
	Upstreams  []string `json:"upstreams"`
	Directives []string `json:"directives"`
}

type HeaderValueConst string

const (
	ProxyHost HeaderValueConst = "$ProxyHost"
)

// HttpServerConfig 定义HTTP服务器配置
type HttpServerConfig struct {
	Name       string `json:"name"`
	ServerName string `json:"server"`
	Port       int    `json:"port"`
	Host       string `json:"host"`
	Paths      []HttpPath `json:"paths"`
	Username   string     `json:"username"`
	Password   string     `json:"password"`
	CertFile   string     `json:"certfile"`
	KeyFile    string     `json:"keyfile"`
	Directives []string   `json:"directives"`
	AuthType   string     `json:"auth_type"`
	Jwt        *JwtConfig `json:"jwt"`
	// 健康检查配置
	HealthCheck *HealthCheckConfig `json:"health_check,omitempty"`
	// 访问控制配置
	AllowIPs []string `json:"allow_ips,omitempty"`  // 允许访问的IP地址列表
	DenyIPs  []string `json:"deny_ips,omitempty"`   // 禁止访问的IP地址列表
}

type JwtConfig struct {
	Secret   string `json:"secret"`
	Expire   int    `json:"expire"`
	Issuer   string `json:"issuer"`
	Audience string `json:"audience"`
}

type GoHttpdConfig struct {
	Logging gologger.LoggersConfig `json:"logging"`
	Admin   *HttpServerConfig      `json:"admin"`
	Servers []*HttpServerConfig    `json:"servers"`
}

var DefaultAdminConfig HttpServerConfig = HttpServerConfig{
	ServerName: "admin",
	Port:       8080,
}

var Config GoHttpdConfig = GoHttpdConfig{}

func GetConfig() *GoHttpdConfig {
	return &Config
}

func SetServerConfig(c *HttpServerConfig) error {
	l := gologger.GetLogger("model")
	updated := false
	for i, s := range Config.Servers {
		if s.Name == c.Name {
			Config.Servers[i] = c
			updated = true
			break
		}
	}
	if !updated {
		Config.Servers = append(Config.Servers, c)
	}
	configFile := utils.NormalizePath("./config.json")
	configsStr, err := json.Marshal(Config)
	if err != nil {
		l.Error("Save config error:", err)
		return err
	}
	werr := os.WriteFile(configFile, configsStr, 0644)
	if werr != nil {
		l.Error("Save config error:", werr)
		return werr
	}
	return nil
}

func GetServerConfig(name string) *HttpServerConfig {
	for _, s := range Config.Servers {
		if s.Name == name {
			return s
		}
	}
	return nil
}
