package config

import (
	"os"
	"path/filepath"
	"strings"
	"testing"
)

func validManagedEdgeConfig() EdgeConfig {
	return EdgeConfig{
		TLS: TLSConf{Enabled: true, Cert: "/cert", Key: "/key", CA: "/ca", PeerRole: "node"},
		ControlPlane: EdgeControlPlaneConf{
			Enabled: true, WireAddr: "control-plane:19081",
			TLS: TLSConf{Enabled: true, Cert: "/cert", Key: "/key", CA: "/ca", ServerName: "control-plane", PeerRole: "control-plane"},
		},
		CredentialPlane: EdgeCredentialPlaneConf{Enabled: true, LeaseTTLSeconds: 30, LeaseCacheSize: 256},
	}
}

func TestCredentialPlaneModeIsSingleExplicitSourceSelector(t *testing.T) {
	for _, tc := range []struct {
		name string
		conf EdgeCredentialPlaneConf
		want CredentialPlaneMode
	}{
		{name: "omitted", conf: EdgeCredentialPlaneConf{}, want: CredentialPlaneModeLegacy},
		{name: "explicit false", conf: EdgeCredentialPlaneConf{Enabled: false}, want: CredentialPlaneModeLegacy},
		{name: "explicit true", conf: EdgeCredentialPlaneConf{Enabled: true}, want: CredentialPlaneModeManaged},
	} {
		t.Run(tc.name, func(t *testing.T) {
			if got := tc.conf.Mode(); got != tc.want {
				t.Fatalf("mode = %v, want %v", got, tc.want)
			}
		})
	}
}

func TestCredentialPlaneDisabledPreservesLegacySources(t *testing.T) {
	for _, enabledLine := range []string{"", "credential_plane:\n  enabled: false\n"} {
		path := filepath.Join(t.TempDir(), "edge.yaml")
		yaml := enabledLine + `
server:
  listen: "127.0.0.1:9090"
openai:
  bearer_token: "legacy-iop-token"
  principal_tokens:
    - token_ref: "legacy-ref"
      token_hash_sha256: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
      principal_ref: "legacy-principal"
  provider_auth:
    enabled: true
`
		if err := os.WriteFile(path, []byte(yaml), 0o600); err != nil {
			t.Fatal(err)
		}
		cfg, err := LoadEdge(path)
		if err != nil {
			t.Fatalf("legacy config rejected: %v", err)
		}
		if cfg.CredentialPlane.Mode() != CredentialPlaneModeLegacy || cfg.OpenAI.BearerToken != "legacy-iop-token" || len(cfg.OpenAI.PrincipalTokens) != 1 || !cfg.OpenAI.ProviderAuth.Enabled {
			t.Fatalf("legacy source changed during load: %+v", cfg.OpenAI)
		}
	}
}

func TestCredentialPlaneEnabledRejectsEveryCompetingSource(t *testing.T) {
	tests := []struct {
		name string
		edit func(*EdgeConfig)
		want string
	}{
		{name: "legacy bearer", edit: func(c *EdgeConfig) { c.OpenAI.BearerToken = "legacy" }, want: "legacy principal or provider auth"},
		{name: "static principal mapping", edit: func(c *EdgeConfig) { c.OpenAI.PrincipalTokens = []OpenAIPrincipalTokenConf{{TokenRef: "ref"}} }, want: "legacy principal or provider auth"},
		{name: "caller provider auth", edit: func(c *EdgeConfig) { c.OpenAI.ProviderAuth.Enabled = true }, want: "legacy principal or provider auth"},
		{name: "provider authorization header", edit: func(c *EdgeConfig) {
			c.Nodes = []NodeDefinition{{Providers: []NodeProviderConf{{Headers: map[string]string{"Authorization": "redacted-fixture"}}}}}
		}, want: "providers[0].headers"},
		{name: "provider URL user info", edit: func(c *EdgeConfig) {
			c.Nodes = []NodeDefinition{{Providers: []NodeProviderConf{{BaseURL: "https://user:redacted-fixture@provider.invalid"}}}}
		}, want: "providers[0].base_url"},
		{name: "custom effective auth header match", edit: func(c *EdgeConfig) {
			c.Nodes = []NodeDefinition{{Providers: []NodeProviderConf{
				{
					ID:   "custom-provider",
					Type: "openai_api",
					Headers: map[string]string{
						"X-Custom-Key": "redacted-fixture",
					},
					RuntimeProfile: &ConcreteProtocolProfile{
						ID: "openai",
						ProtocolProfileConf: ProtocolProfileConf{
							Auth: ProtocolAuthConf{Header: "X-Custom-Key"},
						},
					},
				}},
			}}
		}, want: "providers[0].headers"},
		{name: "resolved profile base URL user info", edit: func(c *EdgeConfig) {
			c.Nodes = []NodeDefinition{{Providers: []NodeProviderConf{
				{
					ID:   "profile-provider",
					Type: "openai_api",
					RuntimeProfile: &ConcreteProtocolProfile{
						ID: "openai",
						ProtocolProfileConf: ProtocolProfileConf{
							Auth:    ProtocolAuthConf{Header: "Authorization"},
							BaseURL: "https://user:redacted-fixture@profile.invalid/v1",
						},
					},
				}},
			}}
		}, want: "profile[\"openai\"].base_url"},
		{name: "resolved absolute operation URL user info", edit: func(c *EdgeConfig) {
			c.Nodes = []NodeDefinition{{Providers: []NodeProviderConf{
				{
					ID:   "op-provider",
					Type: "openai_api",
					RuntimeProfile: &ConcreteProtocolProfile{
						ID: "openai",
						ProtocolProfileConf: ProtocolProfileConf{
							Auth: ProtocolAuthConf{Header: "Authorization"},
							Operations: map[string]string{
								"chat_completions": "https://user:redacted-fixture@op.invalid/v1/chat/completions",
							},
						},
					},
				}},
			}}
		}, want: "profile[\"openai\"].operations"},
		{name: "legacy adapter authorization header", edit: func(c *EdgeConfig) {
			c.Nodes = []NodeDefinition{{Adapters: AdaptersConf{OpenAICompat: OpenAICompatConf{Headers: map[string]string{"Authorization": "redacted-fixture"}}}}}
		}, want: "openai_compat.headers"},
		{name: "adapter authorization header", edit: func(c *EdgeConfig) {
			c.Nodes = []NodeDefinition{{Adapters: AdaptersConf{OpenAICompatInstances: []OpenAICompatInstanceConf{{Headers: map[string]string{"x-api-key": "redacted-fixture"}}}}}}
		}, want: "openai_compat_instances[0].headers"},
		{name: "inherited custom auth header match on named backing adapter", edit: func(c *EdgeConfig) {
			c.Nodes = []NodeDefinition{{
				Providers: []NodeProviderConf{
					{
						ID:      "custom-provider",
						Type:    "openai_api",
						Adapter: "named-backing",
						RuntimeProfile: &ConcreteProtocolProfile{
							ID: "openai",
							ProtocolProfileConf: ProtocolProfileConf{
								Auth: ProtocolAuthConf{Header: "X-Custom-Key"},
							},
						},
					},
				},
				Adapters: AdaptersConf{
					OpenAICompatInstances: []OpenAICompatInstanceConf{
						{
							Name:    "named-backing",
							Enabled: true,
							Headers: map[string]string{"x-custom-key": "redacted-fixture"},
						},
					},
				},
			}}
		}, want: "openai_compat_instances[0].headers"},
		{name: "inherited custom auth header match on legacy type-fallback backing adapter", edit: func(c *EdgeConfig) {
			c.Nodes = []NodeDefinition{{
				Providers: []NodeProviderConf{
					{
						ID:      "custom-provider",
						Type:    "openai_api",
						Adapter: "openai_compat",
						RuntimeProfile: &ConcreteProtocolProfile{
							ID: "openai",
							ProtocolProfileConf: ProtocolProfileConf{
								Auth: ProtocolAuthConf{Header: "X-Custom-Key"},
							},
						},
					},
				},
				Adapters: AdaptersConf{
					OpenAICompatInstances: []OpenAICompatInstanceConf{
						{
							Name:    "fallback-backing",
							Enabled: true,
							Headers: map[string]string{"x-custom-key": "redacted-fixture"},
						},
					},
				},
			}}
		}, want: "openai_compat_instances[0].headers"},
	}
	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			cfg := validManagedEdgeConfig()
			tc.edit(&cfg)
			err := validateEdgeCredentialPlane(&cfg)
			if err == nil || !strings.Contains(err.Error(), tc.want) {
				t.Fatalf("error = %v, want safe path containing %q", err, tc.want)
			}
			if strings.Contains(err.Error(), "redacted-fixture") {
				t.Fatalf("validation error echoed credential value: %v", err)
			}
		})
	}
}

func TestCredentialPlaneEnabledAcceptsUnrelatedCustomHeader(t *testing.T) {
	cfg := validManagedEdgeConfig()
	cfg.Nodes = []NodeDefinition{{
		Providers: []NodeProviderConf{
			{
				ID:   "custom-provider",
				Type: "openai_api",
				Headers: map[string]string{
					"X-Custom-Key": "redacted-fixture",
				},
				RuntimeProfile: &ConcreteProtocolProfile{
					ID: "openai",
					ProtocolProfileConf: ProtocolProfileConf{
						Auth: ProtocolAuthConf{Header: "Authorization"},
					},
				},
			},
		},
		Adapters: AdaptersConf{
			OpenAICompatInstances: []OpenAICompatInstanceConf{
				{
					Name:    "custom-provider",
					Headers: map[string]string{"X-Unrelated-Header": "redacted-fixture"},
				},
			},
		},
	}}
	if err := validateEdgeCredentialPlane(&cfg); err != nil {
		t.Fatalf("unrelated custom header was rejected: %v", err)
	}
}

func TestCredentialPlaneEnabledRequiresCompleteSecureComposition(t *testing.T) {
	valid := validManagedEdgeConfig()
	valid.OpenAI.Enabled = true
	valid.OpenAI.TLS = TLSConf{Enabled: true, Cert: "/cert", Key: "/key"}
	if err := validateEdgeCredentialPlane(&valid); err != nil {
		t.Fatalf("valid managed composition rejected: %v", err)
	}

	tests := []struct {
		name string
		edit func(*EdgeConfig)
	}{
		{name: "lease ttl", edit: func(c *EdgeConfig) { c.CredentialPlane.LeaseTTLSeconds = 0 }},
		{name: "lease cache", edit: func(c *EdgeConfig) { c.CredentialPlane.LeaseCacheSize = 0 }},
		{name: "edge node tls", edit: func(c *EdgeConfig) { c.TLS.Enabled = false }},
		{name: "edge node certificate", edit: func(c *EdgeConfig) { c.TLS.Cert = "" }},
		{name: "edge node key", edit: func(c *EdgeConfig) { c.TLS.Key = "" }},
		{name: "edge node CA", edit: func(c *EdgeConfig) { c.TLS.CA = "" }},
		{name: "control plane disabled", edit: func(c *EdgeConfig) { c.ControlPlane.Enabled = false }},
		{name: "control plane address", edit: func(c *EdgeConfig) { c.ControlPlane.WireAddr = "" }},
		{name: "control plane tls", edit: func(c *EdgeConfig) { c.ControlPlane.TLS.Enabled = false }},
		{name: "control plane certificate", edit: func(c *EdgeConfig) { c.ControlPlane.TLS.Cert = "" }},
		{name: "control plane key", edit: func(c *EdgeConfig) { c.ControlPlane.TLS.Key = "" }},
		{name: "control plane CA", edit: func(c *EdgeConfig) { c.ControlPlane.TLS.CA = "" }},
		{name: "control plane server name", edit: func(c *EdgeConfig) { c.ControlPlane.TLS.ServerName = "" }},
		{name: "openai https", edit: func(c *EdgeConfig) { c.OpenAI.TLS.Enabled = false }},
		{name: "openai certificate", edit: func(c *EdgeConfig) { c.OpenAI.TLS.Cert = "" }},
		{name: "openai key", edit: func(c *EdgeConfig) { c.OpenAI.TLS.Key = "" }},
	}
	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			cfg := valid
			tc.edit(&cfg)
			if err := validateEdgeCredentialPlane(&cfg); err == nil {
				t.Fatal("incomplete managed composition was accepted")
			}
		})
	}
}
