package config

import (
	"fmt"
	"os"
	"strings"

	"github.com/BurntSushi/toml"
)

type Config struct {
	Server     ServerConfig     `toml:"server"`
	EPICS      EPICSConfig      `toml:"datasource.epics"`
	Synthetic  SyntheticConfig  `toml:"datasource.synthetic"`
}

type ServerConfig struct {
	Listen     string `toml:"listen"`
	StorageDir string `toml:"storage_dir"`
}

type EPICSConfig struct {
	Enabled          bool   `toml:"enabled"`
	CAAddrList       string `toml:"ca_addr_list"`
	ArchiveURL       string `toml:"archive_url"`
	ChannelFinderURL string `toml:"channel_finder_url"`
}

type SyntheticConfig struct {
	Enabled         bool   `toml:"enabled"`
	DefinitionsFile string `toml:"definitions_file"`
}

func Default() Config {
	return Config{
		Server: ServerConfig{
			Listen:     ":8080",
			StorageDir: "./interfaces",
		},
		EPICS: EPICSConfig{
			Enabled: true,
		},
		Synthetic: SyntheticConfig{
			Enabled:         true,
			DefinitionsFile: "./synthetic.json",
		},
	}
}

// Load reads a TOML config file and applies environment variable overrides.
// Environment variables use the prefix UOPI_ with __ as separator, e.g.
// UOPI_SERVER_LISTEN=":9090".
func Load(path string) (Config, error) {
	cfg := Default()

	if path != "" {
		if _, err := toml.DecodeFile(path, &cfg); err != nil {
			return cfg, fmt.Errorf("reading config %q: %w", path, err)
		}
	}

	applyEnv(&cfg)
	return cfg, nil
}

func applyEnv(cfg *Config) {
	if v := env("UOPI_SERVER_LISTEN"); v != "" {
		cfg.Server.Listen = v
	}
	if v := env("UOPI_SERVER_STORAGE_DIR"); v != "" {
		cfg.Server.StorageDir = v
	}
	if v := env("UOPI_EPICS_CA_ADDR_LIST"); v != "" {
		cfg.EPICS.CAAddrList = v
	}
	if v := env("UOPI_EPICS_ARCHIVE_URL"); v != "" {
		cfg.EPICS.ArchiveURL = v
	}
	if v := env("UOPI_EPICS_CHANNEL_FINDER_URL"); v != "" {
		cfg.EPICS.ChannelFinderURL = v
	}
	if v := env("UOPI_SYNTHETIC_DEFINITIONS_FILE"); v != "" {
		cfg.Synthetic.DefinitionsFile = v
	}
}

func env(key string) string {
	return strings.TrimSpace(os.Getenv(key))
}
