package api_test

import (
	"testing"

	apicontract "bit.admedia.com/scm/ad/adpilot-indexing-repo-sync.com/internal/contracts/api"
	"bit.admedia.com/scm/ad/adpilot-indexing-repo-sync.com/internal/domain"
)

func TestIndexingRunFromDomain_DegradedWhenFailuresUnderThreshold(t *testing.T) {
	run := domain.IndexingRun{
		IndexingRunID:      "run_test",
		RepoID:             "ad/example",
		SnapshotID:         "snap_test",
		Status:             domain.IndexingRunStatusCompleted,
		ExpectedCodeFiles:  100,
		ProcessedCodeFiles: 100,
		FailedFiles:        3,
		Stages: domain.IndexingRunStages{
			RepoSync:      domain.StageStatusCompleted,
			DocsParse:     domain.StageStatusCompleted,
			CodeParse:     domain.StageStatusCompleted,
			GraphFinalize: domain.StageStatusCompleted,
			CommitIntel:   domain.StageStatusCompleted,
			Embedding:     domain.StageStatusCompleted,
		},
	}

	resp := apicontract.IndexingRunFromDomain(run)
	if resp.PipelineStatus != domain.IndexingRunStatusDegraded {
		t.Fatalf("pipeline_status: got %q, want degraded", resp.PipelineStatus)
	}
	if resp.Progress["code_parse"].FailureRate != 0.03 {
		t.Fatalf("failure_rate: got %v, want 0.03", resp.Progress["code_parse"].FailureRate)
	}
}

func TestIndexingRunFromDomain_FailedWhenCodeParseStageFailed(t *testing.T) {
	run := domain.IndexingRun{
		Status: domain.IndexingRunStatusCompleted,
		Stages: domain.IndexingRunStages{
			RepoSync:  domain.StageStatusCompleted,
			CodeParse: domain.StageStatusFailed,
			Embedding: domain.StageStatusPending,
		},
	}

	resp := apicontract.IndexingRunFromDomain(run)
	if resp.PipelineStatus != domain.IndexingRunStatusFailed {
		t.Fatalf("pipeline_status: got %q, want failed", resp.PipelineStatus)
	}
}

func TestIndexingRunFromDomain_RunningWhileEmbeddingPending(t *testing.T) {
	run := domain.IndexingRun{
		Status: domain.IndexingRunStatusCompleted,
		Stages: domain.IndexingRunStages{
			RepoSync:      domain.StageStatusCompleted,
			CodeParse:     domain.StageStatusCompleted,
			GraphFinalize: domain.StageStatusCompleted,
			CommitIntel:   domain.StageStatusCompleted,
			Embedding:     domain.StageStatusRunning,
		},
	}

	resp := apicontract.IndexingRunFromDomain(run)
	if resp.PipelineStatus != domain.IndexingRunStatusRunning {
		t.Fatalf("pipeline_status: got %q, want running", resp.PipelineStatus)
	}
}

func TestIndexingRunFromDomain_CompletedWhenZeroExpectedCodeParsePending(t *testing.T) {
	run := domain.IndexingRun{
		Status:            domain.IndexingRunStatusRunning,
		ExpectedCodeFiles: 0,
		ExpectedDocsFiles: 0,
		ExpectedCommits:   0,
		Stages: domain.IndexingRunStages{
			RepoSync:      domain.StageStatusCompleted,
			DocsParse:     domain.StageStatusPending,
			CodeParse:     domain.StageStatusPending,
			GraphFinalize: domain.StageStatusCompleted,
			CommitIntel:   domain.StageStatusPending,
			Embedding:     domain.StageStatusCompleted,
		},
	}

	resp := apicontract.IndexingRunFromDomain(run)
	if resp.PipelineStatus != domain.IndexingRunStatusCompleted {
		t.Fatalf("pipeline_status: got %q, want completed", resp.PipelineStatus)
	}
}
