/*
 * Copyright 2026, Jaime Terrats.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { join } from 'node:path';
import { appendJsonlFile } from './file-writer.js';
import { getTask } from './task-state.js';
export function recordDecompositionVote(cwd, taskId, vote) {
    const task = getTask(cwd, taskId);
    if (!task)
        throw new Error(`Task not found: ${taskId}`);
    const existingVotes = task.decompositionVotes ?? [];
    const alreadyVoted = existingVotes.find((v) => v.voter === vote.voter);
    if (alreadyVoted) {
        throw new Error(`${vote.voter} has already voted on decomposition for task ${taskId}`);
    }
    const votes = [...existingVotes, vote];
    const consensus = resolveConsensus(votes);
    const suggestedSplits = collectSplits(votes);
    const updatedTask = {
        ...task,
        decompositionVotes: votes,
        type: consensus === 'decompose' ? 'epic' : task.type,
        event: 'updated',
        updatedAt: new Date().toISOString(),
    };
    appendJsonlFile(join(cwd, '.setup-agents', 'state', 'tasks.jsonl'), updatedTask);
    const state = buildDecompositionState(taskId, updatedTask, votes, consensus, suggestedSplits);
    return { state, task: updatedTask };
}
export function getDecompositionState(cwd, taskId) {
    const task = getTask(cwd, taskId);
    if (!task)
        throw new Error(`Task not found: ${taskId}`);
    const votes = task.decompositionVotes ?? [];
    const consensus = resolveConsensus(votes);
    const suggestedSplits = collectSplits(votes);
    return buildDecompositionState(taskId, task, votes, consensus, suggestedSplits);
}
export function createSubtask(cwd, parentId, subtaskId, summary, roles) {
    const parent = getTask(cwd, parentId);
    if (!parent)
        throw new Error(`Parent task not found: ${parentId}`);
    const now = new Date().toISOString();
    const record = {
        id: subtaskId,
        kind: 'task',
        event: 'created',
        summary,
        status: 'open',
        owner: parent.owner,
        mode: parent.mode,
        type: 'subtask',
        parentId,
        roles: roles ?? parent.roles,
        createdAt: now,
        updatedAt: now,
        evidenceIds: [],
    };
    appendJsonlFile(join(cwd, '.setup-agents', 'state', 'tasks.jsonl'), record);
    return record;
}
export function isDecompositionRequired(run) {
    const baPhase = run.phases.find((p) => p.phase === 'ba');
    const archPhase = run.phases.find((p) => p.phase === 'architect');
    if (baPhase?.notes?.startsWith('Decompose (ba)'))
        return true;
    if (archPhase?.notes?.startsWith('Decompose (architect)'))
        return true;
    return false;
}
function resolveConsensus(votes) {
    if (votes.length === 0)
        return 'pending';
    const baVote = votes.find((v) => v.voter === 'ba');
    const archVote = votes.find((v) => v.voter === 'ta');
    if (!baVote || !archVote)
        return 'pending';
    if (baVote.verdict === 'decompose' || archVote.verdict === 'decompose') {
        return 'decompose';
    }
    return 'proceed';
}
function collectSplits(votes) {
    const splits = new Set();
    for (const vote of votes) {
        if (vote.suggestedSplits) {
            for (const s of vote.suggestedSplits)
                splits.add(s);
        }
    }
    return [...splits];
}
function buildDecompositionState(taskId, task, votes, consensus, suggestedSplits) {
    const baVoted = votes.some((v) => v.voter === 'ba');
    const archVoted = votes.some((v) => v.voter === 'ta');
    let pendingVoter;
    if (!baVoted)
        pendingVoter = 'ba';
    else if (!archVoted)
        pendingVoter = 'ta';
    return {
        taskId,
        taskType: task.type ?? 'story',
        votes,
        consensus,
        pendingVoter,
        suggestedSplits,
    };
}
//# sourceMappingURL=decomposition.js.map