package tags

import "testing"

// fakeProvider is a minimal Provider for registry mechanics tests.
type fakeProvider struct {
	id      string
	deflt   bool
	needKey bool
}

func (f *fakeProvider) ID() string                       { return f.id }
func (f *fakeProvider) DisplayName() string              { return f.id }
func (f *fakeProvider) RequiresAPIKey() bool             { return f.needKey }
func (f *fakeProvider) DefaultEnabled() bool             { return f.deflt }
func (f *fakeProvider) Configure(ProviderSettings) error { return nil }

func TestRegisterAndLookup(t *testing.T) {
	ResetRegistryForTests()
	t.Cleanup(ResetRegistryForTests)

	a := &fakeProvider{id: "alpha", deflt: true}
	b := &fakeProvider{id: "beta"}
	Register(a)
	Register(b)

	all := AllProviders()
	if len(all) != 2 || all[0].ID() != "alpha" || all[1].ID() != "beta" {
		t.Fatalf("AllProviders preserves registration order; got %v", all)
	}

	got, err := ProviderByID("beta")
	if err != nil || got.ID() != "beta" {
		t.Fatalf("ProviderByID(beta) = %v, %v", got, err)
	}
	if _, err := ProviderByID("missing"); err != ErrProviderNotFound {
		t.Fatalf("ProviderByID(missing) err = %v, want ErrProviderNotFound", err)
	}
}

func TestRegisterDuplicatePanics(t *testing.T) {
	ResetRegistryForTests()
	t.Cleanup(ResetRegistryForTests)
	Register(&fakeProvider{id: "dup"})
	defer func() {
		if recover() == nil {
			t.Error("expected panic on duplicate provider ID")
		}
	}()
	Register(&fakeProvider{id: "dup"})
}

// TestBuiltinProvidersRegister confirms the two v1 sources register with
// the expected identities/defaults. Runs against a fresh registry so it is
// independent of test ordering: re-register constructed instances.
func TestBuiltinProvidersRegister(t *testing.T) {
	ResetRegistryForTests()
	t.Cleanup(ResetRegistryForTests)
	Register(&musicbrainzProvider{})
	Register(&lastfmProvider{})

	mb, err := ProviderByID("musicbrainz")
	if err != nil {
		t.Fatalf("musicbrainz not registered: %v", err)
	}
	if mb.RequiresAPIKey() || !mb.DefaultEnabled() {
		t.Errorf("musicbrainz should be keyless + default-on; got key=%v deflt=%v",
			mb.RequiresAPIKey(), mb.DefaultEnabled())
	}
	lf, err := ProviderByID("lastfm")
	if err != nil {
		t.Fatalf("lastfm not registered: %v", err)
	}
	if !lf.RequiresAPIKey() || lf.DefaultEnabled() {
		t.Errorf("lastfm should require a key + default-off; got key=%v deflt=%v",
			lf.RequiresAPIKey(), lf.DefaultEnabled())
	}
	// Both implement the tag-fetch + test capabilities.
	if _, ok := mb.(TrackTagProvider); !ok {
		t.Error("musicbrainz must implement TrackTagProvider")
	}
	if _, ok := lf.(TestableProvider); !ok {
		t.Error("lastfm must implement TestableProvider")
	}
}
