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 { inject, injectable } from 'tsyringe';
import { AgentRunStatus, SdlcLifecycle, } from '../../../domain/generated/output.js';
const ELIGIBLE_RESUME_STATUSES = new Set([
    AgentRunStatus.waitingApproval,
    AgentRunStatus.failed,
    AgentRunStatus.interrupted,
]);
const INELIGIBLE_LIFECYCLES = new Set([
    SdlcLifecycle.Archived,
    SdlcLifecycle.AwaitingUpstream,
    SdlcLifecycle.Blocked,
    SdlcLifecycle.Deleting,
    SdlcLifecycle.Maintain,
]);
function normalizeRequiredString(value, fieldName) {
    const trimmed = value.trim();
    if (!trimmed) {
        throw new Error(`${fieldName} is required`);
    }
    return trimmed;
}
function normalizeRequiredModelId(value) {
    const trimmed = value?.trim();
    if (!trimmed) {
        throw new Error('modelId is required');
    }
    return trimmed;
}
function canUpdatePinnedConfig(feature, run) {
    if (feature.lifecycle === SdlcLifecycle.Pending) {
        return run.status === AgentRunStatus.pending;
    }
    if (INELIGIBLE_LIFECYCLES.has(feature.lifecycle)) {
        return false;
    }
    return ELIGIBLE_RESUME_STATUSES.has(run.status);
}
let UpdateFeaturePinnedConfigUseCase = class UpdateFeaturePinnedConfigUseCase {
    featureRepository;
    agentRunRepository;
    agentExecutorFactory;
    constructor(featureRepository, agentRunRepository, agentExecutorFactory) {
        this.featureRepository = featureRepository;
        this.agentRunRepository = agentRunRepository;
        this.agentExecutorFactory = agentExecutorFactory;
    }
    async execute(input) {
        const featureId = normalizeRequiredString(input.featureId, 'featureId');
        const agentType = normalizeRequiredString(input.agentType, 'agentType');
        const modelId = normalizeRequiredModelId(input.modelId);
        const feature = await this.featureRepository.findById(featureId);
        if (!feature) {
            throw new Error(`Feature not found: ${featureId}`);
        }
        if (!feature.agentRunId) {
            throw new Error(`Feature "${feature.name}" has no current agent run`);
        }
        const run = await this.agentRunRepository.findById(feature.agentRunId);
        if (!run) {
            throw new Error(`Current agent run not found for feature "${feature.name}"`);
        }
        if (!canUpdatePinnedConfig(feature, run)) {
            throw new Error(`Feature "${feature.name}" cannot change pinned agent/model while lifecycle is "${feature.lifecycle}" and run status is "${run.status}"`);
        }
        const supportedAgents = this.agentExecutorFactory.getSupportedAgents();
        if (!supportedAgents.includes(agentType)) {
            throw new Error(`Unsupported agent type: ${agentType}`);
        }
        const availableModels = await this.agentExecutorFactory.listAvailableModels(agentType);
        if (!availableModels.some((m) => m.id === modelId)) {
            throw new Error(`Unsupported model "${modelId}" for agent "${agentType}"`);
        }
        const updatedAt = new Date();
        await this.agentRunRepository.updatePinnedConfig(run.id, {
            agentType,
            modelId,
            updatedAt,
        });
        return {
            featureId: feature.id,
            agentRunId: run.id,
            agentType,
            modelId,
            updatedAt,
        };
    }
};
UpdateFeaturePinnedConfigUseCase = __decorate([
    injectable(),
    __param(0, inject('IFeatureRepository')),
    __param(1, inject('IAgentRunRepository')),
    __param(2, inject('IAgentExecutorFactory')),
    __metadata("design:paramtypes", [Object, Object, Object])
], UpdateFeaturePinnedConfigUseCase);
export { UpdateFeaturePinnedConfigUseCase };
