package kb

import (
	"context"
	"path/filepath"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/AgentTeam/internal/service/automation/runtime"
	"github.com/tidbcloud/AgentTeam/internal/store/resource/repos"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
)

type recordingWikiCheckout struct{ request runtime.CheckoutRequest }

func (checkout *recordingWikiCheckout) Materialize(_ context.Context, request runtime.CheckoutRequest) (runtime.CheckoutResult, error) {
	checkout.request = request
	return runtime.CheckoutResult{}, nil
}

type recordingWikiTreePublisher struct{ request runtime.TreePublishRequest }

func (publisher *recordingWikiTreePublisher) PublishRepositoryTree(_ context.Context, request runtime.TreePublishRequest) (runtime.TreePublishResult, error) {
	publisher.request = request
	return runtime.TreePublishResult{CommitSHA: "insights-commit"}, nil
}

type recordingWikiPublisher struct{ request runtime.WikiPublishRequest }

func (publisher *recordingWikiPublisher) PublishWikiPages(_ context.Context, request runtime.WikiPublishRequest) (runtime.WikiPublishResult, error) {
	publisher.request = request
	return runtime.WikiPublishResult{IndexedCommitSHA: "wiki-commit"}, nil
}

func TestKBWikiRuntimeGeneratorUsesExactRevisionAndBoundedPublishers(t *testing.T) {
	db, err := gorm.Open(sqlite.Open("file:"+t.Name()+"?mode=memory&cache=shared"), &gorm.Config{})
	require.NoError(t, err)
	require.NoError(t, db.AutoMigrate(&repos.ResourceRepository{}))
	repositories := repos.New(db)
	now := time.Date(2026, 8, 9, 2, 3, 4, 0, time.UTC)
	for _, repo := range []repos.ResourceRepository{
		{ID: "mirror", RepoRole: repos.RepoRoleMirror, RepoOwner: "system", RepoName: "source", RepoFullName: "system/source", DefaultRef: "main", Visibility: "private"},
		{ID: "insights", RepoRole: repos.RepoRoleInsights, RepoOwner: "system", RepoName: "insights", RepoFullName: "system/insights", DefaultRef: "generated", Visibility: "private"},
	} {
		repo.WorkspaceID, repo.ResourceType, repo.ResourceID = "ws_1", repos.ResourceTypeKBSource, "src_1"
		repo.OwnerKind, repo.CreatedBy, repo.UpdatedBy = "system", "owner", "owner"
		repo.CreatedAt, repo.UpdatedAt = now, now
		_, err := repositories.Upsert(t.Context(), repo)
		require.NoError(t, err)
	}

	checkout := &recordingWikiCheckout{}
	treePublisher := &recordingWikiTreePublisher{}
	wikiPublisher := &recordingWikiPublisher{}
	var commands [][]string
	workDir := t.TempDir()
	generator := NewKBWikiRuntimeGenerator(KBWikiRuntimeGeneratorConfig{
		Enabled: true, Binary: "agentteam-insight-test", WorkDir: workDir, Timeout: time.Minute,
		CheckoutMaterializer: checkout, TreePublisher: treePublisher,
		WikiPublisher: wikiPublisher, Repositories: repositories,
		Command: func(_ context.Context, binary string, args ...string) error {
			commands = append(commands, append([]string{binary}, args...))
			return nil
		},
	})
	require.NotNil(t, generator)

	output, err := generator.Generate(t.Context(), KBWikiGenerationInput{
		WorkspaceID: "ws_1", KnowledgeBaseID: "kb_1", SourceID: "src_1",
		SourceRevision: "rev_1", SourceCommitSHA: "source-commit", Scope: "full",
		Language: "zh", RequestID: "request_1",
	})
	require.NoError(t, err)
	require.Equal(t, KBWikiGenerationOutput{InsightsCommitSHA: "insights-commit", PublishedWikiCommit: "wiki-commit"}, output)
	require.Equal(t, "system/source", checkout.request.RepositoryFullName)
	require.Equal(t, "source-commit", checkout.request.CommitSHA)
	require.True(t, checkout.request.Clean)
	require.Equal(t, [][]string{
		{"agentteam-insight-test", "graph", "--input", filepath.Join(workDir, "request_1", "source"), "--output", filepath.Join(workDir, "request_1", "analysis"), "--mode", "full", "--no-prompt", "--output-language", "zh"},
		{"agentteam-insight-test", "wiki", "--input", filepath.Join(workDir, "request_1", "source"), "--input", filepath.Join(workDir, "request_1", "analysis"), "--output", filepath.Join(workDir, "request_1", "wiki"), "--output-language", "zh"},
	}, commands)
	require.Equal(t, "system/insights", treePublisher.request.Repository)
	require.Equal(t, "generated", treePublisher.request.DefaultBranch)
	require.Equal(t, filepath.Join(workDir, "request_1", "analysis"), treePublisher.request.SourcePath)
	require.Equal(t, "system/insights", wikiPublisher.request.Repository)
	require.Equal(t, filepath.Join(workDir, "request_1", "wiki"), wikiPublisher.request.SourcePath)
	require.NoDirExists(t, filepath.Join(workDir, "request_1"))
}

func TestKBWikiRuntimeGeneratorRequiresAllProductionDependencies(t *testing.T) {
	require.Nil(t, NewKBWikiRuntimeGenerator(KBWikiRuntimeGeneratorConfig{Enabled: true}))
}
