/**
 * Resume Feature Use Case
 *
 * Resumes an interrupted, failed, or waiting_approval feature agent run.
 * Creates a new AgentRun record and spawns a worker with --resume flag.
 */
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
import { injectable, inject } from 'tsyringe';
import { randomUUID } from 'node:crypto';
import { AgentRunStatus } from '../../../domain/generated/output.js';
const RESUMABLE_STATUSES = new Set([
    AgentRunStatus.interrupted,
    AgentRunStatus.failed,
    AgentRunStatus.waitingApproval,
]);
let ResumeFeatureUseCase = class ResumeFeatureUseCase {
    featureRepo;
    runRepo;
    processService;
    worktreeService;
    constructor(featureRepo, runRepo, processService, worktreeService) {
        this.featureRepo = featureRepo;
        this.runRepo = runRepo;
        this.processService = processService;
        this.worktreeService = worktreeService;
    }
    async execute(featureId) {
        // Resolve feature by exact ID or prefix
        const feature = (await this.featureRepo.findById(featureId)) ??
            (await this.featureRepo.findByIdPrefix(featureId));
        if (!feature) {
            throw new Error(`Feature not found: ${featureId}`);
        }
        // Load the most recent agent run
        if (!feature.agentRunId) {
            throw new Error(`No agent run found for feature "${feature.name}"`);
        }
        const lastRun = await this.runRepo.findById(feature.agentRunId);
        if (!lastRun) {
            throw new Error(`No agent run found for feature "${feature.name}"`);
        }
        // Validate the run is in a resumable state
        if (lastRun.status === AgentRunStatus.running) {
            throw new Error('Agent is still running — stop it first before resuming');
        }
        if (lastRun.status === AgentRunStatus.completed) {
            throw new Error('Agent already completed successfully');
        }
        if (!RESUMABLE_STATUSES.has(lastRun.status)) {
            throw new Error(`Agent run is not in a resumable state (status: ${lastRun.status})`);
        }
        // Create a new agent run record that continues the same thread
        const now = new Date();
        const newRunId = randomUUID();
        const newRun = {
            id: newRunId,
            agentType: lastRun.agentType,
            agentName: lastRun.agentName,
            status: AgentRunStatus.pending,
            prompt: lastRun.prompt,
            threadId: lastRun.threadId, // Same thread for checkpoint continuity
            featureId: feature.id,
            repositoryPath: feature.repositoryPath,
            approvalMode: lastRun.approvalMode,
            createdAt: now,
            updatedAt: now,
        };
        await this.runRepo.create(newRun);
        // Update feature to reference the new run
        await this.featureRepo.update({
            ...feature,
            agentRunId: newRunId,
            updatedAt: now,
        });
        // Derive worktree path and spawn resume worker
        const worktreePath = this.worktreeService.getWorktreePath(feature.repositoryPath, feature.branch);
        this.processService.spawn(feature.id, newRunId, feature.repositoryPath, worktreePath, worktreePath, { resume: true, approvalMode: lastRun.approvalMode });
        return { feature, newRun };
    }
};
ResumeFeatureUseCase = __decorate([
    injectable(),
    __param(0, inject('IFeatureRepository')),
    __param(1, inject('IAgentRunRepository')),
    __param(2, inject('IFeatureAgentProcessService')),
    __param(3, inject('IWorktreeService')),
    __metadata("design:paramtypes", [Object, Object, Object, Object])
], ResumeFeatureUseCase);
export { ResumeFeatureUseCase };
