package helpers

import (
	"errors"
	"fmt"
	"os"
)

type ConfigParameter struct {
	EnvVarName   string `json:"env_var_name"`
	ConfFilePath string `json:"conf_file_path"`
	DefaultValue string `json:"default_value"`
	FailIfAbsent bool   `json:"fail_if_absent"`
}

type Configuration struct {
	VstpOn   bool   `json:"vstp_on"`
	NrodUser string `json:"nrod_user"`
	NrodPass string `json:"nrod_pass"`
	DbHost   string `json:"db_host"`
	DbPass   string `json:"db_pass"`
	DbUser   string `json:"db_user"`
	DbPort   string `json:"db_port"`
}

func LoadConfig() (*Configuration, error) {
	configParams := map[string]ConfigParameter{
		"vstp_on": {
			EnvVarName:   "OWL_VSTP_ON",
			ConfFilePath: "/owl/conf/vstp/on",
			DefaultValue: "on",
			FailIfAbsent: false,
		},
		"nrod_user": {
			EnvVarName:   "OWL_NROD_USER",
			ConfFilePath: "/owl/conf/nrod/user",
			FailIfAbsent: true,
		},
		"nrod_pass": {
			EnvVarName:   "OWL_NROD_PASS",
			ConfFilePath: "/owl/conf/nrod/pass",
			FailIfAbsent: true,
		},
		"db_host": {
			EnvVarName:   "OWL_DB_HOST",
			ConfFilePath: "/owl/conf/db/host",
			DefaultValue: "localhost",
			FailIfAbsent: false,
		},
		"db_port": {
			EnvVarName:   "OWL_DB_PORT",
			ConfFilePath: "/owl/conf/db/port",
			DefaultValue: "27017",
			FailIfAbsent: false,
		},
		"db_user": {
			EnvVarName:   "OWL_DB_USER",
			ConfFilePath: "/owl/conf/db/user",
			FailIfAbsent: true,
		},
		"db_pass": {
			EnvVarName:   "OWL_DB_PASS",
			ConfFilePath: "/owl/conf/db/pass",
			FailIfAbsent: true,
		},
	}

	config := &Configuration{}

	for key, param := range configParams {
		if val, ok := os.LookupEnv(param.EnvVarName); ok {
			config.setConfigValue(key, val)
			continue
		}

		if data, err := os.ReadFile(param.ConfFilePath); err == nil {
			config.setConfigValue(key, string(data))
			continue
		}

		if param.DefaultValue != "" {
			config.setConfigValue(key, param.DefaultValue)
			continue
		}

		if param.FailIfAbsent {
			return nil, errors.New("Failed to load configuration: " + key + " is required but not set")
		}
	}

	return config, nil
}

func (c *Configuration) setConfigValue(key, value string) {
	switch key {
	case "nrod_user":
		c.NrodUser = value
	case "nrod_pass":
		c.NrodPass = value
	case "db_host":
		c.DbHost = value
	case "db_port":
		c.DbPort = value
	case "db_user":
		c.DbUser = value
	case "db_pass":
		c.DbPass = value
	case "vstp_on":
		if value == "on" {
			c.VstpOn = true
		} else {
			c.VstpOn = false
		}
	}
}

func (c *Configuration) PrintConfig() {
	if os.Getenv("DEBUG") == "true" {
		fmt.Println("Configuration:")
		fmt.Println("VstpOn: ", c.VstpOn)
		fmt.Println("NrodUser: ", c.NrodUser)
		fmt.Println("NrodPass: ", c.NrodPass)
		fmt.Println("DbHost: ", c.DbHost)
		fmt.Println("DbUser: ", c.DbUser)
		fmt.Println("DbPass: ", c.DbPass)
		fmt.Println("DbPort: ", c.DbPort)
	}
}
