/**
 * Worker Task Service
 *
 * This service provides the complete workflow for workers picking up tasks
 * and working in isolated worktrees. It orchestrates:
 * - Task dispatch to worker
 * - Worktree creation for task isolation
 * - Worker spawning in the worktree
 * - Task context delivery to worker
 * - Task completion with branch ready for merge
 *
 * @module
 */
import { createTimestamp } from '@stoneforge/core';
// ============================================================================
// Worker Task Service Implementation
// ============================================================================
/**
 * Implementation of the Worker Task Service.
 */
export class WorkerTaskServiceImpl {
    api;
    taskAssignment;
    agentRegistry;
    dispatchService;
    worktreeManager;
    // Note: SpawnerService kept for potential future use (e.g., sending input to sessions)
    // Currently we interact with sessions through SessionManager
    _spawnerService;
    sessionManager;
    constructor(api, taskAssignment, agentRegistry, dispatchService, spawnerService, sessionManager, worktreeManager) {
        this.api = api;
        this.taskAssignment = taskAssignment;
        this.agentRegistry = agentRegistry;
        this.dispatchService = dispatchService;
        this._spawnerService = spawnerService;
        this.sessionManager = sessionManager;
        this.worktreeManager = worktreeManager;
    }
    // ----------------------------------------
    // Task Lifecycle
    // ----------------------------------------
    async startWorkerOnTask(taskId, agentId, options = {}) {
        const startedAt = createTimestamp();
        // 1. Get agent info to verify it's a worker
        const agent = await this.agentRegistry.getAgent(agentId);
        if (!agent) {
            throw new Error(`Agent not found: ${agentId}`);
        }
        const agentMeta = agent.metadata?.agent;
        if (agentMeta?.agentRole !== 'worker') {
            throw new Error(`Agent ${agentId} is not a worker (role: ${agentMeta?.agentRole})`);
        }
        // 2. Get task info
        const task = await this.api.get(taskId);
        if (!task) {
            throw new Error(`Task not found: ${taskId}`);
        }
        // 3. Create worktree if enabled and not skipped
        let worktreeResult;
        let workingDirectory = options.workingDirectory;
        let branch = options.branch;
        let worktreePath = options.worktreePath;
        if (this.worktreeManager && !options.skipWorktree) {
            worktreeResult = await this.worktreeManager.createWorktree({
                agentName: agent.name ?? `agent-${agentId.substring(0, 8)}`,
                taskId,
                taskTitle: task.title,
                customBranch: options.branch,
                customPath: options.worktreePath,
                baseBranch: options.baseBranch,
            });
            workingDirectory = worktreeResult.path;
            branch = worktreeResult.branch;
            worktreePath = worktreeResult.path;
        }
        // 4. Dispatch the task (assigns + notifies)
        const dispatchOptions = {
            branch,
            worktree: worktreePath,
            priority: options.priority,
            markAsStarted: true,
            dispatchedBy: options.performedBy,
        };
        const dispatchResult = await this.dispatchService.dispatch(taskId, agentId, dispatchOptions);
        // 5. Build task context prompt
        const taskContextPrompt = await this.buildTaskContextPrompt(taskId, agentId, options.additionalPrompt);
        // 6. Start the worker session in the worktree
        const { session } = await this.sessionManager.startSession(agentId, {
            workingDirectory,
            worktree: worktreePath,
            initialPrompt: taskContextPrompt,
            interactive: false, // Workers are typically headless
        });
        // 7. Update task with session ID
        await this.taskAssignment.updateSessionId(taskId, session.id);
        return {
            task: dispatchResult.task,
            agent,
            dispatch: dispatchResult,
            worktree: worktreeResult,
            session,
            taskContextPrompt,
            startedAt,
        };
    }
    async completeTask(taskId, options = {}) {
        const completedAt = createTimestamp();
        // 1. Get task to verify it exists and is in progress
        const task = await this.api.get(taskId);
        if (!task) {
            throw new Error(`Task not found: ${taskId}`);
        }
        // 2. Mark the task as completed using TaskAssignmentService
        const completeResult = await this.taskAssignment.completeTask(taskId, {
            summary: options.summary,
            commitHash: options.commitHash,
        });
        // 3. Get worktree info if applicable
        let worktree;
        const orchestratorMeta = completeResult.task.metadata?.orchestrator;
        if (this.worktreeManager && orchestratorMeta?.worktree) {
            worktree = await this.worktreeManager.getWorktree(orchestratorMeta.worktree);
        }
        // 4. The task is now ready for merge (merge status set to 'pending' by completeTask)
        return {
            task: completeResult.task,
            worktree,
            readyForMerge: true,
            completedAt,
        };
    }
    // ----------------------------------------
    // Task Context
    // ----------------------------------------
    async buildTaskContextPrompt(taskId, workerId, additionalInstructions) {
        const context = await this.getTaskContext(taskId);
        const lines = [
            '# Task Assignment',
            '',
            `**Worker ID:** ${workerId}`,
            `**Task ID:** ${context.taskId}`,
            `**Title:** ${context.title}`,
        ];
        if (context.description) {
            lines.push('', '## Description', '', context.description);
        }
        if (context.priority) {
            lines.push(`**Priority:** ${context.priority}`);
        }
        if (context.complexity) {
            lines.push(`**Complexity:** ${context.complexity}`);
        }
        if (context.tags.length > 0) {
            lines.push(`**Tags:** ${context.tags.join(', ')}`);
        }
        if (context.branch) {
            lines.push('', '## Git Information', '');
            lines.push(`**Branch:** ${context.branch}`);
            if (context.worktreePath) {
                lines.push(`**Working Directory:** ${context.worktreePath}`);
            }
        }
        lines.push('', '## Instructions', '');
        lines.push('1. Work on this task in the current working directory.', '2. Make commits as you progress (use clear commit messages).', '3. When complete, use the stoneforge CLI to close the task:', '   `sf task close ' + context.taskId + '`', '4. The Merge Steward will then review and merge your changes.');
        if (additionalInstructions || context.additionalInstructions) {
            lines.push('', '## Additional Instructions', '', additionalInstructions || context.additionalInstructions || '');
        }
        return lines.join('\n');
    }
    async getTaskContext(taskId) {
        const task = await this.api.get(taskId);
        if (!task) {
            throw new Error(`Task not found: ${taskId}`);
        }
        const metadata = task.metadata;
        return {
            taskId,
            title: task.title,
            description: metadata?.description,
            tags: task.tags ?? [],
            priority: task.priority,
            complexity: task.complexity,
            branch: metadata?.orchestrator?.branch,
            worktreePath: metadata?.orchestrator?.worktree,
        };
    }
    // ----------------------------------------
    // Cleanup
    // ----------------------------------------
    async cleanupTask(taskId, deleteBranch = false) {
        // Get task to find worktree info
        const task = await this.api.get(taskId);
        if (!task) {
            return false;
        }
        const orchestratorMeta = task.metadata?.orchestrator;
        if (!orchestratorMeta?.worktree) {
            // No worktree to clean up
            return true;
        }
        if (!this.worktreeManager) {
            // Worktree manager not available
            return false;
        }
        try {
            await this.worktreeManager.removeWorktree(orchestratorMeta.worktree, {
                deleteBranch,
                force: false,
            });
            return true;
        }
        catch {
            // Worktree removal failed
            return false;
        }
    }
}
// ============================================================================
// Factory Function
// ============================================================================
/**
 * Creates a WorkerTaskService instance
 */
export function createWorkerTaskService(api, taskAssignment, agentRegistry, dispatchService, spawnerService, sessionManager, worktreeManager) {
    return new WorkerTaskServiceImpl(api, taskAssignment, agentRegistry, dispatchService, spawnerService, sessionManager, worktreeManager);
}
//# sourceMappingURL=worker-task-service.js.map