package config

import (
	"testing"
	"time"
)

func validConfig() Config {
	return Config{
		Version: CurrentConfigVersion,
		Server:  ServerConfig{Port: 8080},
		MCP:     MCPConfig{Path: "/mcp", SessionTimeout: 10 * time.Minute},
		Auth: AuthConfig{
			Keys: []APIKey{{ID: "test", Value: "secret"}},
		},
		Database: DatabaseConfig{URL: "postgres://example"},
		AI: AIConfig{
			Providers: map[string]ProviderConfig{
				"default": {Type: "litellm", BaseURL: "http://localhost:4000/v1", APIKey: "key"},
			},
			Embeddings: EmbeddingsRoleConfig{
				Dimensions: 1536,
				Primary:    RoleTarget{Provider: "default", Model: "text-embed"},
			},
			Metadata: MetadataRoleConfig{
				Primary: RoleTarget{Provider: "default", Model: "gpt-4"},
			},
		},
		Search:  SearchConfig{DefaultLimit: 10, MaxLimit: 50},
		Logging: LoggingConfig{Level: "info"},
	}
}

func TestValidateAcceptsSupportedProviderTypes(t *testing.T) {
	for _, providerType := range []string{"litellm", "ollama", "openrouter"} {
		cfg := validConfig()
		p := cfg.AI.Providers["default"]
		p.Type = providerType
		cfg.AI.Providers["default"] = p
		if err := cfg.Validate(); err != nil {
			t.Fatalf("Validate %s error = %v", providerType, err)
		}
	}
}

func TestValidateRejectsInvalidProviderType(t *testing.T) {
	cfg := validConfig()
	p := cfg.AI.Providers["default"]
	p.Type = "unknown"
	cfg.AI.Providers["default"] = p

	if err := cfg.Validate(); err == nil {
		t.Fatal("Validate() error = nil, want error for unsupported provider type")
	}
}

func TestValidateRejectsChainWithUnknownProvider(t *testing.T) {
	cfg := validConfig()
	cfg.AI.Metadata.Primary = RoleTarget{Provider: "does-not-exist", Model: "x"}

	if err := cfg.Validate(); err == nil {
		t.Fatal("Validate() error = nil, want error for chain referencing unknown provider")
	}
}

func TestValidateRejectsEmptyProviders(t *testing.T) {
	cfg := validConfig()
	cfg.AI.Providers = map[string]ProviderConfig{}

	if err := cfg.Validate(); err == nil {
		t.Fatal("Validate() error = nil, want error for empty providers")
	}
}

func TestValidateRejectsEmptyAuthKeyValue(t *testing.T) {
	cfg := validConfig()
	cfg.Auth.Keys[0].Value = ""

	if err := cfg.Validate(); err == nil {
		t.Fatal("Validate() error = nil, want error for empty auth key value")
	}
}

func TestValidateAcceptsOAuthClients(t *testing.T) {
	cfg := validConfig()
	cfg.Auth = AuthConfig{
		OAuth: OAuthConfig{
			Clients: []OAuthClient{{
				ID:           "oauth-client",
				ClientID:     "client-id",
				ClientSecret: "client-secret",
			}},
		},
	}

	if err := cfg.Validate(); err != nil {
		t.Fatalf("Validate() error = %v", err)
	}
}

func TestValidateAcceptsBothAuthMethods(t *testing.T) {
	cfg := validConfig()
	cfg.Auth = AuthConfig{
		Keys: []APIKey{{ID: "key1", Value: "secret"}},
		OAuth: OAuthConfig{
			Clients: []OAuthClient{{
				ID:           "oauth-client",
				ClientID:     "client-id",
				ClientSecret: "client-secret",
			}},
		},
	}

	if err := cfg.Validate(); err != nil {
		t.Fatalf("Validate() error = %v", err)
	}
}

func TestValidateRejectsEmptyAuth(t *testing.T) {
	cfg := validConfig()
	cfg.Auth = AuthConfig{}

	if err := cfg.Validate(); err == nil {
		t.Fatal("Validate() error = nil, want error when neither auth.keys nor auth.oauth.clients is configured")
	}
}

func TestValidateRejectsInvalidMetadataRetryConfig(t *testing.T) {
	cfg := validConfig()
	cfg.MetadataRetry.Enabled = true
	cfg.MetadataRetry.MaxPerRun = 0

	if err := cfg.Validate(); err == nil {
		t.Fatal("Validate() error = nil, want error for invalid metadata retry config")
	}
}

func TestValidateRejectsInvalidMCPSessionTimeout(t *testing.T) {
	cfg := validConfig()
	cfg.MCP.SessionTimeout = 0

	if err := cfg.Validate(); err == nil {
		t.Fatal("Validate() error = nil, want error for invalid mcp session timeout")
	}
}
