package config

import (
	"encoding/json"
	"fmt"
	"os"
	"path"
)

const GATOR_CONFIG_FILE = ".gatorconfig.json"

type Config struct {
	DbUrl           string `json:"db_url"`
	CurrentUserName string `json:"current_user_name"`
}

func Read() (*Config, error) {
	config := Config{}

	configFilePath, err := getConfigPath()

	if err != nil {
		return nil, err
	}

	data, err := os.ReadFile(configFilePath)

	if err != nil {
		return nil, err
	}

	err = json.Unmarshal(data, &config)

	if err != nil {
		return nil, err
	}

	return &config, nil
}

// TODO: I don't think there should be
// hidden I/O in this method call
func (c *Config) SetUser(currentUserName string) error {
	c.CurrentUserName = currentUserName
	return writeFile(c)
}

func (c *Config) String() string {
	return fmt.Sprintf("Config { DbUrl = %s, CurrentUserName = %s }", c.DbUrl, c.CurrentUserName)
}

func writeFile(config *Config) error {
	data, err := json.Marshal(config)

	if err != nil {
		return err
	}

	configFilePath, err := getConfigPath()

	if err != nil {
		return err
	}

	file, err := os.Create(configFilePath)

	if err != nil {
		return err
	}

	defer file.Close()

	_, err = file.Write(data)

	if err != nil {
		return err
	}

	return nil
}

func getConfigPath() (string, error) {
	homeDir, err := os.UserHomeDir()

	if err != nil {
		return "", err
	}

	configFilePath := path.Join(homeDir, GATOR_CONFIG_FILE)

	return configFilePath, nil
}
