package config

import (
	"errors"
	"fmt"
	"os"
	"path/filepath"

	"helmet/pkg/client"

	"go.yaml.in/yaml/v4"
)

const (
	configFilename = "minilbd.yaml"
)

var (
	buildVersion = "NONE"
)

type Service struct {
	Port uint32 `json:"port" yaml:"port"`
}

type Auth struct {
	Username string `json:"username" yaml:"username"`
	Password string `json:"password" yaml:"password"`
}

type Config struct {
	Service  Service `json:"service"    yaml:"service"`
	Auths    []Auth  `json:"auths"      yaml:"auths"`
	Hostname string  `json:"hostname"   yaml:"hostname"`
	LogPath  string  `json:"logfile"    yaml:"logfile"`
	RunPath  string  `json:"runfile"    yaml:"runfile"`
	AsDaemon bool    `json:"asDaemon"   yaml:"asDaemon"`
	LogLimit int64   `json:"logLimit"   yaml:logLimit`
	RunUser  string  `json:"runUser"    yaml:runUser`
}

func NewConfig() (*Config, error) {
	conf := &Config{
		Service: Service{
			Port: client.DefaultServicePort,
		},
		AsDaemon: false,
		LogLimit: 1024 * 1024 * 10, // 10 Mb
		RunUser:  "daemon",
	}
	hostname, err := os.Hostname()
	if err != nil {
		return conf, err
	}
	conf.Hostname = hostname
	exeName := filepath.Base(os.Args[0])
	conf.LogPath = filepath.Join(logdirPath, fmt.Sprintf("%s.log", exeName))
	conf.RunPath = filepath.Join(rundirPath, fmt.Sprintf("%s.pid", exeName))
	return conf, err
}

func (conf *Config) Read() error {
	var err error
	configPath := filepath.Join(confdirPath, configFilename)
	confBytes, err := os.ReadFile(configPath)
	if err != nil {
		return err
	}
	err = yaml.Unmarshal(confBytes, conf)
	if err != nil {
		return err
	}
	return err
}

func (conf *Config) Validate() error {
	var err []error
	for i := range conf.Auths {
		if conf.Auths[i].Username == "" {
			err = append(err, errors.New("Username must be set"))
		}
		if conf.Auths[i].Password == "" {
			err = append(err, errors.New("Password must be set"))
		}
	}
	return errors.Join(err...)
}

func (conf *Config) YAML() (string, error) {
	var err error
	var res string
	yamlBytes, err := yaml.Marshal(conf)
	if err != nil {
		return res, err
	}
	res = string(yamlBytes)
	return res, err
}
