package usecase

import (
	"context"
	"testing"

	"haixun-backend/internal/model/job/domain/entity"
	"haixun-backend/internal/model/job/domain/enum"

	"go.mongodb.org/mongo-driver/bson/primitive"
)

func TestRetryRun_PreservesSucceededSteps(t *testing.T) {
	ctx := context.Background()
	template := demoTemplate()
	jobID := primitive.NewObjectID()
	runs := newMemoryRunRepo(&entity.Run{
		ID:           jobID,
		TemplateType: template.Type,
		Status:       enum.RunStatusFailed,
		WorkerType:   "go",
		Attempt:      1,
		MaxAttempts:  3,
		Phase:        "execute",
		Progress: entity.RunProgress{
			Steps: []entity.StepProgress{
				{ID: "prepare", Status: enum.StepStatusSucceeded, Message: "done"},
				{ID: "execute", Status: enum.StepStatusFailed, Message: "boom"},
				{ID: "finalize", Status: enum.StepStatusPending},
			},
		},
	})
	uc := testUseCaseFull(template, runs, nil, newMemoryQueueRepo())

	updated, err := uc.RetryRun(ctx, jobID.Hex())
	if err != nil {
		t.Fatalf("RetryRun() error = %v", err)
	}
	if updated.Progress.Steps[0].Status != enum.StepStatusSucceeded {
		t.Fatalf("prepare = %s, want succeeded", updated.Progress.Steps[0].Status)
	}
	if updated.Progress.Steps[1].Status != enum.StepStatusPending {
		t.Fatalf("execute = %s, want pending", updated.Progress.Steps[1].Status)
	}
	if updated.Phase != "execute" {
		t.Fatalf("phase = %s, want execute", updated.Phase)
	}
	if updated.Progress.Percentage != 33 {
		t.Fatalf("percentage = %d, want 33", updated.Progress.Percentage)
	}
}

func TestRetryRun_ExpiredResumesFromCheckpoint(t *testing.T) {
	ctx := context.Background()
	template := demoTemplate()
	jobID := primitive.NewObjectID()
	runs := newMemoryRunRepo(&entity.Run{
		ID:           jobID,
		TemplateType: template.Type,
		Status:       enum.RunStatusExpired,
		WorkerType:   "go",
		Attempt:      1,
		MaxAttempts:  3,
		DedupeKey:    "dedupe-expired",
		Progress: entity.RunProgress{
			Steps: []entity.StepProgress{
				{ID: "prepare", Status: enum.StepStatusSucceeded},
				{ID: "execute", Status: enum.StepStatusRunning},
				{ID: "finalize", Status: enum.StepStatusPending},
			},
		},
	})
	uc := testUseCaseFull(template, runs, nil, newMemoryQueueRepo())

	updated, err := uc.RetryRun(ctx, jobID.Hex())
	if err != nil {
		t.Fatalf("RetryRun() error = %v", err)
	}
	if updated.Progress.Steps[0].Status != enum.StepStatusSucceeded {
		t.Fatalf("prepare = %s, want succeeded", updated.Progress.Steps[0].Status)
	}
	if updated.Phase != "execute" {
		t.Fatalf("phase = %s, want execute", updated.Phase)
	}
}
