package automation

import (
	"context"
	"errors"
	"testing"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/AgentTeam/internal/store/content"
)

type routedAutomationAuthority struct {
	authority content.Authority
	found     bool
	err       error
}

func (reader routedAutomationAuthority) GetAuthority(context.Context, string, string, string) (content.Authority, bool, error) {
	return reader.authority, reader.found, reader.err
}

type routedAutomationSource struct {
	name  string
	err   error
	calls int
}

func (source *routedAutomationSource) ResolveAutomationSource(context.Context, AutomationSourceRequest) (AutomationSourceSnapshot, error) {
	source.calls++
	return AutomationSourceSnapshot{Content: source.name}, source.err
}

func (*routedAutomationSource) ListAutomationRepositories(context.Context, string, int, int) ([]AutomationSourceRepository, error) {
	return nil, nil
}

func (*routedAutomationSource) ListAutomationOrgRepositories(context.Context, string, string, int, int) ([]AutomationSourceRepository, error) {
	return nil, nil
}

func (*routedAutomationSource) ListAutomationFiles(context.Context, AutomationSourceRequest) ([]AutomationSourceFile, error) {
	return nil, nil
}

func (*routedAutomationSource) GetAutomationFile(context.Context, AutomationSourceRequest) (AutomationSourceContent, error) {
	return AutomationSourceContent{}, nil
}

func (*routedAutomationSource) PutAutomationFile(context.Context, AutomationSourceWriteRequest) (AutomationSourceWriteResult, error) {
	return AutomationSourceWriteResult{}, nil
}

func (*routedAutomationSource) DeleteAutomationFile(context.Context, AutomationSourceDeleteRequest) error {
	return nil
}

func TestAuthorityRoutedAutomationSourceNeverFallsBackAfterActivation(t *testing.T) {
	request := AutomationSourceRequest{WorkspaceID: "wsp_1", RepositoryOwner: "team", RepositoryName: "repo"}
	legacy := &routedAutomationSource{name: "legacy"}
	native := &routedAutomationSource{name: "native", err: errors.New("native unavailable")}
	source := AuthorityRoutedAutomationSource{NativeEnabled: true, Authority: routedAutomationAuthority{}, Legacy: legacy, Native: native}

	resolved, err := source.ResolveAutomationSource(t.Context(), request)
	require.NoError(t, err)
	require.Equal(t, "legacy", resolved.Content)
	require.Equal(t, 1, legacy.calls)

	source.Authority = routedAutomationAuthority{found: true, authority: content.Authority{State: content.AuthorityStateNativeActive, Generation: 1}}
	_, err = source.ResolveAutomationSource(t.Context(), request)
	require.ErrorContains(t, err, "native unavailable")
	require.Equal(t, 1, legacy.calls, "native failure must not invoke AGS")
	require.Equal(t, 1, native.calls)

	source.NativeEnabled = false
	_, err = source.ResolveAutomationSource(t.Context(), request)
	require.ErrorContains(t, err, "native automation content is unavailable")
	require.Equal(t, 1, legacy.calls, "config-off restart must not fall back after activation")
}

func TestAuthorityRoutedAutomationSourceFailsClosedOnUnknownState(t *testing.T) {
	legacy := &routedAutomationSource{name: "legacy"}
	source := AuthorityRoutedAutomationSource{
		NativeEnabled: true,
		Authority:     routedAutomationAuthority{found: true, authority: content.Authority{State: "retired", Generation: 2}},
		Legacy:        legacy,
		Native:        &routedAutomationSource{name: "native"},
	}
	_, err := source.ResolveAutomationSource(t.Context(), AutomationSourceRequest{WorkspaceID: "wsp_1", RepositoryOwner: "team", RepositoryName: "repo"})
	require.ErrorContains(t, err, "unknown automation content authority state")
	require.Zero(t, legacy.calls)
}
