package controller

import (
    "errors"
    "fmt"
    "os"
    "strconv"

    "arimelody-web/model"

    "github.com/pelletier/go-toml/v2"
)

func GetConfig() model.Config {
    configFile := os.Getenv("ARIMELODY_CONFIG")
    if configFile == "" {
        configFile = "config.toml"
    }

    config := model.Config{
        BaseUrl: "https://arimelody.me",
        Host: "0.0.0.0",
        Port: 8080,
        TrustedProxies: []string{ "127.0.0.1" },
        DB: model.DBConfig{
            Host: "127.0.0.1",
            Port: 5432,
            User: "arimelody",
            Name: "arimelody",
        },
    }

    data, err := os.ReadFile(configFile)
    if err != nil {
        configOut, _ := toml.Marshal(&config)
        os.WriteFile(configFile, configOut, os.ModePerm)
        fmt.Printf(
            "A default config.toml has been created. " +
            "Please configure before running again!\n")
        os.Exit(0)
    }

    err = toml.Unmarshal([]byte(data), &config)
    if err != nil {
        panic(fmt.Sprintf("FATAL: Failed to parse configuration file: %v\n", err))
    }

    err = handleConfigOverrides(&config)
    if err != nil {
        panic(fmt.Sprintf("FATAL: Failed to parse environment variable %v\n", err))
    }

    return config
}

func handleConfigOverrides(config *model.Config) error {
    var err error

    if env, has := os.LookupEnv("ARIMELODY_BASE_URL"); has { config.BaseUrl = env }
    if env, has := os.LookupEnv("ARIMELODY_HOST"); has { config.Host = env }
    if env, has := os.LookupEnv("ARIMELODY_PORT"); has {
        config.Port, err = strconv.ParseInt(env, 10, 0)
        if err != nil { return errors.New("ARIMELODY_PORT: " + err.Error()) }
    }
    if env, has := os.LookupEnv("ARIMELODY_DATA_DIR"); has { config.DataDirectory = env }

    if env, has := os.LookupEnv("ARIMELODY_DB_HOST"); has { config.DB.Host = env }
    if env, has := os.LookupEnv("ARIMELODY_DB_PORT"); has {
        config.DB.Port, err = strconv.ParseInt(env, 10, 0)
        if err != nil { return errors.New("ARIMELODY_DB_PORT: " + err.Error()) }
    }
    if env, has := os.LookupEnv("ARIMELODY_DB_NAME"); has { config.DB.Name = env }
    if env, has := os.LookupEnv("ARIMELODY_DB_USER"); has { config.DB.User = env }
    if env, has := os.LookupEnv("ARIMELODY_DB_PASS"); has { config.DB.Pass = env }

    if env, has := os.LookupEnv("ARIMELODY_DISCORD_ADMIN_ID"); has { config.Discord.AdminID = env }
    if env, has := os.LookupEnv("ARIMELODY_DISCORD_CLIENT_ID"); has { config.Discord.ClientID = env }
    if env, has := os.LookupEnv("ARIMELODY_DISCORD_SECRET"); has { config.Discord.Secret = env }

    return nil
}
