package providers_test

import (
	"strings"
	"testing"

	"github.com/salvacybersec/keyhunter/pkg/providers"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"gopkg.in/yaml.v3"
)

func TestRegistryLoad(t *testing.T) {
	reg, err := providers.NewRegistry()
	require.NoError(t, err)
	assert.GreaterOrEqual(t, len(reg.List()), 3, "expected at least 3 providers")
}

func TestRegistryGet(t *testing.T) {
	reg, err := providers.NewRegistry()
	require.NoError(t, err)

	p, ok := reg.Get("openai")
	assert.True(t, ok)
	assert.Equal(t, "openai", p.Name)
	assert.Equal(t, 1, p.Tier)

	_, notOk := reg.Get("nonexistent-provider")
	assert.False(t, notOk)
}

func TestRegistryStats(t *testing.T) {
	reg, err := providers.NewRegistry()
	require.NoError(t, err)

	stats := reg.Stats()
	assert.GreaterOrEqual(t, stats.Total, 3)
	assert.GreaterOrEqual(t, stats.ByTier[1], 2)
}

func TestAhoCorasickBuild(t *testing.T) {
	reg, err := providers.NewRegistry()
	require.NoError(t, err)

	ac := reg.AC()
	matches := ac.FindAll("export OPENAI_API_KEY=sk-proj-abc")
	assert.NotEmpty(t, matches)

	noMatches := ac.FindAll("hello world nothing here")
	assert.Empty(t, noMatches)
}

func TestTier1VerifySpecs_Complete(t *testing.T) {
	reg, err := providers.NewRegistry()
	require.NoError(t, err)

	// Tier 1 providers that must have a usable verify endpoint.
	// Note: inflection is Tier 1 but intentionally excluded — no public verify endpoint.
	tier1 := []string{
		"openai", "anthropic", "google-ai", "cohere", "mistral",
		"groq", "xai", "ai21", "perplexity", "deepseek", "together",
	}
	for _, name := range tier1 {
		p, ok := reg.Get(name)
		if !ok {
			t.Errorf("provider %q not in registry", name)
			continue
		}
		if p.Verify.URL == "" {
			t.Errorf("provider %q: verify.url must be set", name)
			continue
		}
		if !strings.HasPrefix(p.Verify.URL, "https://") {
			t.Errorf("provider %q: verify.url must be HTTPS, got %q", name, p.Verify.URL)
		}
		if len(p.Verify.EffectiveSuccessCodes()) == 0 {
			t.Errorf("provider %q: no success codes configured", name)
		}
	}
}

func TestInflection_NoVerifyEndpoint(t *testing.T) {
	reg, err := providers.NewRegistry()
	require.NoError(t, err)

	p, ok := reg.Get("inflection")
	if !ok {
		t.Skip("inflection provider not loaded")
	}
	assert.Equal(t, "", p.Verify.URL, "inflection should have empty verify.url (no public endpoint)")
}

func TestProviderSchemaValidation(t *testing.T) {
	invalid := []byte("format_version: 0\nname: invalid\nlast_verified: \"\"\n")
	var p providers.Provider
	err := yaml.Unmarshal(invalid, &p)
	assert.Error(t, err)
	assert.Contains(t, err.Error(), "format_version")
}
