// Package config handles application configuration.
package config

import (
	"os"
	"path/filepath"
	"runtime"
	"strconv"

	"git.eeqj.de/sneak/smartconfig"
)

// Config holds the application configuration.
type Config struct {
	Port     int
	StateDir string
	LogLevel string
}

// New creates a new configuration instance.
func New(configFile string) (*Config, error) {
	// Check if config file exists first
	if _, err := os.Stat(configFile); os.IsNotExist(err) {
		return newDefaultConfig(), nil
	}

	// Load smartconfig
	sc, err := smartconfig.NewFromConfigPath(configFile)
	if err != nil {
		return nil, err
	}

	cfg := &Config{}

	// Get port from smartconfig or environment or default
	if port, err := sc.GetInt("port"); err == nil {
		cfg.Port = port
	} else {
		cfg.Port = getPortFromEnv()
	}

	// Get state directory
	if stateDir, err := sc.GetString("state_dir"); err == nil {
		cfg.StateDir = stateDir
	} else {
		cfg.StateDir = getDefaultStateDir()
	}

	// Get log level
	if logLevel, err := sc.GetString("log_level"); err == nil {
		cfg.LogLevel = logLevel
	} else {
		cfg.LogLevel = "info"
	}

	return cfg, nil
}

func newDefaultConfig() *Config {
	return &Config{
		Port:     getPortFromEnv(),
		StateDir: getDefaultStateDir(),
		LogLevel: "info",
	}
}

func getPortFromEnv() int {
	const defaultPort = 8080
	portStr := os.Getenv("PORT")
	if portStr == "" {
		return defaultPort
	}
	port, err := strconv.Atoi(portStr)
	if err != nil {
		return defaultPort
	}

	return port
}

func getDefaultStateDir() string {
	switch runtime.GOOS {
	case "darwin":
		// macOS: use ~/Library/Application Support/berlin.sneak.app.ipapi/
		home, err := os.UserHomeDir()
		if err != nil {
			return "/var/lib/ipapi"
		}

		return filepath.Join(home, "Library", "Application Support", "berlin.sneak.app.ipapi")
	case "windows":
		// Windows: use %APPDATA%\berlin.sneak.app.ipapi
		appData := os.Getenv("APPDATA")
		if appData == "" {
			return "/var/lib/ipapi"
		}

		return filepath.Join(appData, "berlin.sneak.app.ipapi")
	default:
		// Linux and other Unix-like systems
		return "/var/lib/ipapi"
	}
}
