package config

import (
	"log"
	"os"
	"strconv"
	"strings"
	"time"
)

type Config struct {
	ServerURL string
	AuthToken string

	LatencyInterval time.Duration
	TraceInterval   time.Duration

	XrayAccessLogPath string
	XrayLogStateFile  string
	XrayLogInterval   time.Duration
	XrayLogStartAtEnd bool
}

func Load() *Config {
	cfg := &Config{
		ServerURL:         envOrDefault("SERVER_URL", ""),
		AuthToken:         envOrDefault("AUTH_TOKEN", ""),
		LatencyInterval:   envDuration("LATENCY_INTERVAL", 5*time.Minute),
		TraceInterval:     envDuration("TRACE_INTERVAL", 30*time.Minute),
		XrayAccessLogPath: envOrDefault("XRAY_ACCESS_LOG_PATH", ""),
		XrayLogStateFile:  envOrDefault("XRAY_LOG_STATE_FILE", "/var/lib/jboard-agent/xray-log-state.json"),
		XrayLogInterval:   envDuration("XRAY_LOG_INTERVAL", time.Minute),
		XrayLogStartAtEnd: envBool("XRAY_LOG_START_AT_END", true),
	}

	if cfg.ServerURL == "" || cfg.AuthToken == "" {
		log.Fatal("[config] SERVER_URL and AUTH_TOKEN are required")
	}

	return cfg
}

func envOrDefault(key, fallback string) string {
	if v := os.Getenv(key); v != "" {
		return v
	}
	return fallback
}

func envDuration(key string, fallback time.Duration) time.Duration {
	v := os.Getenv(key)
	if v == "" {
		return fallback
	}

	if d, err := time.ParseDuration(v); err == nil {
		return d
	}

	if seconds, err := strconv.Atoi(v); err == nil && seconds > 0 {
		return time.Duration(seconds) * time.Second
	}

	return fallback
}

func envBool(key string, fallback bool) bool {
	v := os.Getenv(key)
	if v == "" {
		return fallback
	}

	switch strings.ToLower(strings.TrimSpace(v)) {
	case "1", "true", "yes", "y", "on":
		return true
	case "0", "false", "no", "n", "off":
		return false
	default:
		return fallback
	}
}
