package approvalapp

import (
	"context"
	"testing"
	"time"

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

type fakeWikiGenerationTerminalAuthority struct {
	terminal kbgovernance.WikiGenerationTerminal
}

func (authority fakeWikiGenerationTerminalAuthority) InspectWikiGenerationTerminal(_ context.Context, command kbgovernance.InspectWikiGenerationTerminalCommand) (kbgovernance.WikiGenerationTerminal, error) {
	if command.WorkspaceID != authority.terminal.WorkspaceID || command.RequestID != authority.terminal.RequestID {
		return kbgovernance.WikiGenerationTerminal{}, context.Canceled
	}
	return authority.terminal, nil
}

func TestWikiGenerationTerminalGatewayProjectsRequesterResult(t *testing.T) {
	ctx := context.Background()
	now := time.Now().UTC().Truncate(time.Second)
	db := startApprovalAppRollbackDB(t, ctx)
	workspaceID := "wsp_kb_wiki_terminal"
	seedApprovalAppWorkspace(t, db, workspaceID, now)
	seedWikiApprovalHuman(t, db, workspaceID, "usr_wiki_terminal", "mem_wiki_terminal", "admin", now)

	notifications := app.New(db, app.Options{})
	projector := NewProjector(notifications, NewProvisioner(db))
	require.NoError(t, projector.Register())
	terminal := wikiGenerationTerminalFixture(kbgovernance.WikiGenerationTerminalReady, "", "wiki-sha")
	terminal.WorkspaceID = workspaceID
	terminal.RequesterID = "usr_wiki_terminal"
	gateway := NewWikiGenerationTerminalGateway(fakeWikiGenerationTerminalAuthority{terminal: terminal}, db, projector)
	command := kbgovernance.NotifyWikiGenerationTerminalCommand{
		WorkspaceID: workspaceID, RequestID: terminal.RequestID, ExpectedVersion: terminal.Version,
	}
	require.NoError(t, gateway.NotifyWikiGenerationTerminal(ctx, command))
	require.NoError(t, gateway.NotifyWikiGenerationTerminal(ctx, command))

	provisioned, err := projector.provisioner.EnsureWorkspace(ctx, workspaceID, now)
	require.NoError(t, err)
	record, found, err := notifications.FindAppNotificationByClientID(ctx, workspaceID, provisioned.Installation.ID, wikiGenerationTerminalClientNotificationID(terminal.RequestID))
	require.NoError(t, err)
	require.True(t, found)
	require.Equal(t, app.AppNotificationStatusActive, record.Status)
	require.NotNil(t, record.RecipientBasisKind)
	require.Equal(t, RecipientBasisWikiGenerationRequester, *record.RecipientBasisKind)
	require.NotNil(t, record.BusinessObjectType)
	require.Equal(t, BusinessTypeWikiGenerationRequest, *record.BusinessObjectType)
	require.Equal(t, int64(1), rowCount(t, ctx, db, `
SELECT COUNT(*) FROM service_notifications
WHERE workspace_id = $1 AND client_notification_id = $2
`, workspaceID, wikiGenerationTerminalClientNotificationID(terminal.RequestID)))
}
