/**
 * Create Feature Use Case
 *
 * Creates a new feature entity with a git worktree for isolated development,
 * initializes the spec directory with YAML templates, then spawns the
 * feature agent to begin autonomous SDLC processing.
 *
 * Business Rules:
 * - AI generates slug/name/description from user's free-text input
 * - Falls back to regex-based slug if AI fails
 * - Full user input is preserved as-is in spec.yaml
 * - Slug must be unique within the repository
 * - A git worktree is created at ~/.shep/repos/HASH/wt/SLUG/
 * - Spec YAML files are scaffolded at WORKTREE/specs/NNN-SLUG/
 * - Feature agent is spawned with the spec dir path
 * - specPath is persisted on the Feature record
 * - Initial lifecycle is Requirements
 */
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 { SdlcLifecycle } from '../../../domain/generated/output.js';
import { AgentRunStatus } from '../../../domain/generated/output.js';
import { getSettings } from '../../../infrastructure/services/settings.service.js';
/** Maximum characters of user input sent to the AI for metadata generation. */
const MAX_INPUT_FOR_AI = 500;
let CreateFeatureUseCase = class CreateFeatureUseCase {
    featureRepo;
    worktreeService;
    agentProcess;
    runRepository;
    specInitializer;
    executorFactory;
    constructor(featureRepo, worktreeService, agentProcess, runRepository, specInitializer, executorFactory) {
        this.featureRepo = featureRepo;
        this.worktreeService = worktreeService;
        this.agentProcess = agentProcess;
        this.runRepository = runRepository;
        this.specInitializer = specInitializer;
        this.executorFactory = executorFactory;
    }
    async execute(input) {
        const metadata = await this.generateMetadata(input.userInput);
        const slug = metadata.slug;
        const branch = `feat/${slug}`;
        const existing = await this.featureRepo.findBySlug(slug, input.repositoryPath);
        if (existing) {
            throw new Error(`Feature with slug "${slug}" already exists in this repository`);
        }
        // Determine next feature number for this repo
        const existingFeatures = await this.featureRepo.list({
            repositoryPath: input.repositoryPath,
        });
        const featureNumber = existingFeatures.length + 1;
        const now = new Date();
        const runId = randomUUID();
        // Create git worktree for isolated development
        const worktreePath = this.worktreeService.getWorktreePath(input.repositoryPath, branch);
        await this.worktreeService.create(input.repositoryPath, branch, worktreePath);
        // Initialize spec directory — full user input goes into spec.yaml as-is
        const { specDir } = await this.specInitializer.initialize(worktreePath, slug, featureNumber, input.userInput);
        const feature = {
            id: randomUUID(),
            name: metadata.name,
            slug,
            description: metadata.description,
            repositoryPath: input.repositoryPath,
            branch,
            lifecycle: SdlcLifecycle.Requirements,
            messages: [],
            relatedArtifacts: [],
            agentRunId: runId,
            specPath: specDir,
            createdAt: now,
            updatedAt: now,
        };
        await this.featureRepo.create(feature);
        // Create agent run record and spawn background worker
        const settings = getSettings();
        const agentRun = {
            id: runId,
            agentType: settings.agent.type,
            agentName: 'feature-agent',
            status: AgentRunStatus.pending,
            prompt: input.userInput,
            threadId: randomUUID(),
            featureId: feature.id,
            repositoryPath: input.repositoryPath,
            ...(input.approvalMode ? { approvalMode: input.approvalMode } : {}),
            createdAt: now.toISOString(),
            updatedAt: now.toISOString(),
        };
        await this.runRepository.create(agentRun);
        this.agentProcess.spawn(feature.id, runId, input.repositoryPath, specDir, worktreePath, input.approvalMode ? { approvalMode: input.approvalMode } : undefined);
        return feature;
    }
    async generateMetadata(userInput) {
        try {
            const settings = getSettings();
            const executor = this.executorFactory.createExecutor(settings.agent.type, settings.agent);
            const truncated = userInput.length > MAX_INPUT_FOR_AI
                ? `${userInput.slice(0, MAX_INPUT_FOR_AI)}...`
                : userInput;
            const prompt = `Generate feature metadata from this user request:
"${truncated}"

Return ONLY a JSON object with these fields:
- slug: kebab-case identifier, 2-4 words max (e.g., "github-oauth-login")
- name: short human-readable title (e.g., "GitHub OAuth Login")
- description: refined 1-2 sentence description

JSON only, no markdown fences.`;
            const result = await executor.execute(prompt, {
                maxTurns: 1,
                allowedTools: [],
                silent: true,
            });
            const parsed = JSON.parse(result.result);
            if (!parsed.slug || !parsed.name || !parsed.description) {
                throw new Error('Missing required fields in AI response');
            }
            return {
                slug: this.toSlug(parsed.slug),
                name: parsed.name,
                description: parsed.description,
            };
        }
        catch {
            // Fallback to regex-based slug generation
            return {
                slug: this.toSlug(userInput),
                name: userInput,
                description: userInput,
            };
        }
    }
    toSlug(text) {
        return text
            .toLowerCase()
            .replace(/[^a-z0-9\s-]/g, '')
            .replace(/\s+/g, '-')
            .replace(/-+/g, '-')
            .replace(/^-|-$/g, '');
    }
};
CreateFeatureUseCase = __decorate([
    injectable(),
    __param(0, inject('IFeatureRepository')),
    __param(1, inject('IWorktreeService')),
    __param(2, inject('IFeatureAgentProcessService')),
    __param(3, inject('IAgentRunRepository')),
    __param(4, inject('ISpecInitializerService')),
    __param(5, inject('IAgentExecutorFactory')),
    __metadata("design:paramtypes", [Object, Object, Object, Object, Object, Object])
], CreateFeatureUseCase);
export { CreateFeatureUseCase };
