import { execFileSync } from 'node:child_process';
import { formatIssueAsTask, formatPrReviewAsTask, getGitProvider, } from '../../infra/git/index.js';
import { resolveConfigValue } from '../../infra/config/index.js';
import { stageAndCommit, resolveBaseBranch, pushBranch, checkoutBranch } from '../../infra/task/index.js';
import { executeTask, confirmAndCreateWorktree } from '../tasks/index.js';
import { info, error, success } from '../../shared/ui/index.js';
import { statusLine } from '../../shared/ui/StatusLine.js';
import { getErrorMessage } from '../../shared/utils/index.js';
import { sanitizeTerminalText } from '../../shared/utils/text.js';
import { expandPipelineTemplate } from './templateExpander.js';
function requireBaseBranch(baseBranch, context) {
    if (!baseBranch) {
        throw new Error(`Base branch is required (${context})`);
    }
    return baseBranch;
}
function requireBranch(branch, context) {
    if (!branch) {
        throw new Error(`Branch is required (${context})`);
    }
    return branch;
}
function generatePipelineBranchName(pipelineConfig, issueNumber) {
    const prefix = pipelineConfig?.defaultBranchPrefix ?? 'takt/';
    const timestamp = Math.floor(Date.now() / 1000);
    return issueNumber
        ? `${prefix}issue-${issueNumber}-${timestamp}`
        : `${prefix}pipeline-${timestamp}`;
}
export function buildCommitMessage(pipelineConfig, issue, taskText) {
    const template = pipelineConfig?.commitMessageTemplate;
    if (template && issue) {
        return expandPipelineTemplate(template, {
            title: issue.title,
            issue: String(issue.number),
        });
    }
    return issue
        ? `feat: ${issue.title} (#${issue.number})`
        : `takt: ${taskText ?? 'pipeline task'}`;
}
function resolveExecutionBaseBranch(cwd, preferredBaseBranch) {
    const { branch } = resolveBaseBranch(cwd, preferredBaseBranch);
    return requireBaseBranch(branch, 'execution context');
}
function fetchVcsResource(label, cwd, fetch) {
    const gitProvider = getGitProvider();
    const cliStatus = gitProvider.checkCliStatus(cwd);
    if (!cliStatus.available) {
        error(cliStatus.error);
        return undefined;
    }
    try {
        return fetch(gitProvider);
    }
    catch (err) {
        error(`Failed to fetch ${label}: ${getErrorMessage(err)}`);
        return undefined;
    }
}
export function resolveTaskContent(options) {
    const { cwd } = options;
    if (options.prNumber) {
        info(`Fetching PR #${options.prNumber} review comments...`);
        const prReview = fetchVcsResource(`PR #${options.prNumber}`, cwd, (provider) => provider.fetchPrReviewComments(options.prNumber, cwd));
        if (!prReview)
            return undefined;
        const task = formatPrReviewAsTask(prReview);
        success(`PR #${options.prNumber} fetched: "${sanitizeTerminalText(prReview.title)}"`);
        return {
            task,
            prBranch: prReview.headRefName,
            prBaseBranch: prReview.baseRefName,
        };
    }
    if (options.issueNumber) {
        info(`Fetching issue #${options.issueNumber}...`);
        const issue = fetchVcsResource(`issue #${options.issueNumber}`, cwd, (provider) => provider.fetchIssue(options.issueNumber, cwd));
        if (!issue)
            return undefined;
        const task = formatIssueAsTask(issue);
        success(`Issue #${options.issueNumber} fetched: "${sanitizeTerminalText(issue.title)}"`);
        return { task, issue };
    }
    if (options.task) {
        return { task: options.task };
    }
    error('Either --issue, --pr, or --task must be specified');
    return undefined;
}
export async function resolveExecutionContext(cwd, task, options, pipelineConfig, prBranch, prBaseBranch) {
    if (options.createWorktree) {
        const result = await confirmAndCreateWorktree(cwd, task, options.createWorktree, prBranch, prBaseBranch);
        const branch = requireBranch(result.branch, 'worktree execution');
        const baseBranch = requireBaseBranch(result.baseBranch, 'worktree execution');
        if (result.isWorktree) {
            success(`Worktree created: ${sanitizeTerminalText(result.execCwd)}`);
        }
        return {
            execCwd: result.execCwd,
            branch,
            baseBranch,
            isWorktree: result.isWorktree,
        };
    }
    if (options.skipGit) {
        return {
            execCwd: cwd,
            isWorktree: false,
            branch: undefined,
            baseBranch: undefined,
        };
    }
    if (prBranch) {
        const safePrBranch = sanitizeTerminalText(prBranch);
        info(`Fetching and checking out PR branch: ${safePrBranch}`);
        checkoutBranch(cwd, prBranch);
        success(`Checked out PR branch: ${safePrBranch}`);
        const baseBranch = resolveExecutionBaseBranch(cwd, prBaseBranch);
        return {
            execCwd: cwd,
            branch: prBranch,
            baseBranch,
            isWorktree: false,
        };
    }
    const baseBranch = resolveExecutionBaseBranch(cwd);
    const branch = options.branch ?? generatePipelineBranchName(pipelineConfig, options.issueNumber);
    const safeBranch = sanitizeTerminalText(branch);
    info(`Creating branch: ${safeBranch}`);
    execFileSync('git', ['checkout', '-b', branch], { cwd, stdio: 'pipe' });
    success(`Branch created: ${safeBranch}`);
    return { execCwd: cwd, branch, baseBranch, isWorktree: false };
}
export async function runWorkflow(projectCwd, workflow, task, execCwd, options) {
    const safeWorkflow = sanitizeTerminalText(workflow);
    info(`Running workflow: ${safeWorkflow}`);
    const agentOverrides = (options.provider || options.model)
        ? { provider: options.provider, model: options.model }
        : undefined;
    statusLine.start('Running...');
    let taskSuccess;
    try {
        taskSuccess = await executeTask({
            task,
            cwd: execCwd,
            workflowIdentifier: workflow,
            projectCwd,
            agentOverrides,
        });
    }
    finally {
        statusLine.stop();
    }
    if (!taskSuccess) {
        error(`Workflow '${safeWorkflow}' failed`);
        return false;
    }
    success(`Workflow '${safeWorkflow}' completed`);
    return true;
}
export function commitAndPush(execCwd, projectCwd, branch, commitMessage, isWorktree) {
    const safeBranch = sanitizeTerminalText(branch);
    info('Committing changes...');
    try {
        const commitHash = stageAndCommit(execCwd, commitMessage, {
            allowGitHooks: resolveConfigValue(projectCwd, 'allowGitHooks') ?? false,
            allowGitFilters: resolveConfigValue(projectCwd, 'allowGitFilters') ?? false,
        });
        if (commitHash) {
            success(`Changes committed: ${commitHash}`);
        }
        else {
            info('No changes to commit');
        }
        if (isWorktree) {
            execFileSync('git', ['push', projectCwd, 'HEAD'], { cwd: execCwd, stdio: 'pipe' });
        }
        info(`Pushing to origin/${safeBranch}...`);
        pushBranch(projectCwd, branch);
        success(`Pushed to origin/${safeBranch}`);
        return true;
    }
    catch (err) {
        error(`Git operation failed: ${getErrorMessage(err)}`);
        return false;
    }
}
//# sourceMappingURL=steps.js.map