package catalogreconcile

import (
	"context"
	"testing"

	"github.com/nexuscrm/metadata/catalogsnapshot"
)

type effectiveOAuthAuthorityReaderStub struct {
	connectedApps []EffectiveOAuthAuthorityEntry
	scopes        []EffectiveOAuthAuthorityEntry
}

func (s effectiveOAuthAuthorityReaderStub) GetEffectiveConnectedApps(
	context.Context,
) ([]EffectiveOAuthAuthorityEntry, error) {
	return s.connectedApps, nil
}

func (s effectiveOAuthAuthorityReaderStub) GetEffectiveOAuthCustomScopes(
	context.Context,
) ([]EffectiveOAuthAuthorityEntry, error) {
	return s.scopes, nil
}

func TestBuildEffectiveOAuthAuthorityComponentsPublishesCompleteSet(t *testing.T) {
	components, err := buildEffectiveOAuthAuthorityComponents(
		context.Background(),
		effectiveOAuthAuthorityReaderStub{
			connectedApps: []EffectiveOAuthAuthorityEntry{
				{BusinessKey: "public-bi", OwnerPack: "crm"},
			},
			scopes: []EffectiveOAuthAuthorityEntry{
				{BusinessKey: "External.Records.Read", OwnerPack: "crm"},
			},
		},
	)
	if err != nil {
		t.Fatal(err)
	}
	identities := make(map[string]struct{}, len(components))
	for _, component := range components {
		identities[component.ComponentKind+"\x00"+component.BusinessKey] = struct{}{}
	}
	for _, identity := range []string{
		catalogsnapshot.EffectiveOAuthAuthorityMarkerComponentKind + "\x00" +
			catalogsnapshot.EffectiveOAuthAuthorityMarkerBusinessKey,
		catalogsnapshot.EffectiveConnectedAppComponentKind + "\x00public-bi",
		catalogsnapshot.EffectiveOAuthCustomScopeComponentKind + "\x00external.records.read",
	} {
		if _, ok := identities[identity]; !ok {
			t.Fatalf("effective OAuth component %q is missing: %#v", identity, components)
		}
	}
}

func TestBuildEffectiveOAuthAuthorityComponentsRejectsFoldedScopeDuplicate(t *testing.T) {
	_, err := buildEffectiveOAuthAuthorityComponents(
		context.Background(),
		effectiveOAuthAuthorityReaderStub{scopes: []EffectiveOAuthAuthorityEntry{
			{BusinessKey: "scope.read"},
			{BusinessKey: "SCOPE.READ"},
		}},
	)
	if err == nil {
		t.Fatal("duplicate scope was accepted")
	}
}
