package app

import (
	"testing"
	"time"
)

func TestParseAppMode(t *testing.T) {
	t.Parallel()

	tests := []struct {
		name      string
		value     string
		want      string
		expectErr bool
	}{
		{name: "default", value: "", want: "development"},
		{name: "production", value: "production", want: "production"},
		{name: "normalized", value: " StAgInG ", want: "staging"},
		{name: "invalid", value: "prod", expectErr: true},
	}

	for _, test := range tests {
		test := test
		t.Run(test.name, func(t *testing.T) {
			t.Parallel()
			got, err := parseAppMode(test.value)
			if test.expectErr {
				if err == nil {
					t.Fatalf("expected error for %q", test.value)
				}
				return
			}
			if err != nil {
				t.Fatalf("did not expect error: %v", err)
			}
			if got != test.want {
				t.Fatalf("parseAppMode(%q) = %q, want %q", test.value, got, test.want)
			}
		})
	}
}

func TestParseDuration(t *testing.T) {
	t.Parallel()

	got, err := parseDuration("", 10*time.Second, "API_SHUTDOWN_TIMEOUT")
	if err != nil {
		t.Fatalf("did not expect error: %v", err)
	}
	if got != 10*time.Second {
		t.Fatalf("parseDuration default = %s, want 10s", got)
	}

	got, err = parseDuration("15s", 10*time.Second, "API_SHUTDOWN_TIMEOUT")
	if err != nil {
		t.Fatalf("did not expect error: %v", err)
	}
	if got != 15*time.Second {
		t.Fatalf("parseDuration explicit = %s, want 15s", got)
	}

	if _, err := parseDuration("0s", 10*time.Second, "API_SHUTDOWN_TIMEOUT"); err == nil {
		t.Fatal("expected zero duration to fail")
	}
	if _, err := parseDuration("nope", 10*time.Second, "API_SHUTDOWN_TIMEOUT"); err == nil {
		t.Fatal("expected invalid duration to fail")
	}
}

func TestParseCORSAllowOrigins(t *testing.T) {
	t.Parallel()

	devOrigins, err := parseCORSAllowOrigins("development", "")
	if err != nil {
		t.Fatalf("did not expect error: %v", err)
	}
	if len(devOrigins) == 0 {
		t.Fatal("expected default development origins")
	}

	if _, err := parseCORSAllowOrigins("production", ""); err == nil {
		t.Fatal("expected production with empty CORS_ALLOW_ORIGINS to fail")
	}

	origins, err := parseCORSAllowOrigins("production", "https://app.example.com, https://app.example.com ,https://admin.example.com")
	if err != nil {
		t.Fatalf("did not expect error: %v", err)
	}
	if len(origins) != 2 {
		t.Fatalf("expected 2 deduplicated origins, got %d", len(origins))
	}

	if _, err := parseCORSAllowOrigins("production", "*"); err == nil {
		t.Fatal("expected wildcard origin to fail")
	}

	if _, err := parseCORSAllowOrigins("production", "https://app.example.com/path"); err == nil {
		t.Fatal("expected origin with path to fail")
	}
}

func TestIsInsecureSecret(t *testing.T) {
	t.Parallel()

	if !isInsecureSecret("replace-me-with-a-long-random-secret") {
		t.Fatal("expected placeholder secret to be insecure")
	}
	if !isInsecureSecret("short") {
		t.Fatal("expected short secret to be insecure")
	}
	if isInsecureSecret("this-is-a-strong-enough-secret-12345") {
		t.Fatal("expected long random secret to pass")
	}
}

func TestResolveMetricsAuthToken(t *testing.T) {
	t.Run("empty token is allowed", func(t *testing.T) {
		t.Setenv("METRICS_AUTH_TOKEN", "")
		token, err := resolveMetricsAuthToken("production")
		if err != nil {
			t.Fatalf("did not expect error: %v", err)
		}
		if token != "" {
			t.Fatalf("token = %q, want empty", token)
		}
	})

	t.Run("rejects weak token in production", func(t *testing.T) {
		t.Setenv("METRICS_AUTH_TOKEN", "short")
		if _, err := resolveMetricsAuthToken("production"); err == nil {
			t.Fatal("expected weak production token to fail")
		}
	})

	t.Run("allows token in production", func(t *testing.T) {
		t.Setenv("METRICS_AUTH_TOKEN", "this-is-a-strong-enough-secret-98765")
		token, err := resolveMetricsAuthToken("production")
		if err != nil {
			t.Fatalf("did not expect error: %v", err)
		}
		if token == "" {
			t.Fatal("expected resolved token")
		}
	})
}
