import { getExternalSnapshotForSession } from "../agents/shared/agent-activity.js";
import { isExternalSnapshotSuppressedByManagedAbort } from "./relay-runtime-helpers.js";
export async function relayRuntimeSessionWorktrees(runtime) {
    const contexts = runtime.listKnownContextMetadata()
        .filter((meta) => meta.threadId || meta.workspace)
        .map((meta) => ({
        agentId: meta.agentId,
        threadId: meta.threadId,
        contextKey: meta.contextKey,
        workspace: meta.workspace,
    }));
    return runtime.worktreeService.listDashboardSnapshot(contexts);
}
export async function relayRuntimeCommitSessionWorktree(runtime, id, message, actor) {
    const result = runtime.worktreeService.commit(id, message);
    runtime.appendActivity({
        source: "web",
        status: "completed",
        type: "worktree_committed",
        threadId: result.record.threadId ?? null,
        workspace: result.record.worktreePath,
        agentId: result.record.agentId,
        actor,
        detail: result.clean ? "No changes; recorded current HEAD." : `Committed ${result.record.commitSha ?? result.record.branchName}.`,
    });
    return result;
}
export async function relayRuntimeSessionWorktreeDiff(runtime, id) {
    return runtime.worktreeService.diff(id);
}
export async function relayRuntimeCompareSessionWorktrees(runtime, ids) {
    return runtime.worktreeService.compare(ids);
}
export async function relayRuntimePreviewSessionWorktreeIntegration(runtime, ids) {
    return runtime.worktreeService.previewIntegration(ids);
}
export async function relayRuntimeExportSessionWorktreeIntegrationPatch(runtime, ids) {
    return runtime.worktreeService.exportIntegrationPatch(ids);
}
export async function relayRuntimeUpdateSessionWorktreeFromBase(runtime, id, actor) {
    const result = runtime.worktreeService.updateFromBase(id);
    runtime.appendActivity({
        source: "web",
        status: result.record.status === "conflict" ? "failed" : "info",
        type: "worktree_updated_from_base",
        threadId: result.record.threadId ?? null,
        workspace: result.record.worktreePath,
        agentId: result.record.agentId,
        actor,
        detail: result.rebased ? `Rebased ${result.record.branchName} onto ${result.newBaseSha}.` : "Worktree already used the latest base.",
    });
    return result;
}
export async function relayRuntimeCleanupSessionWorktrees(runtime, actor) {
    const result = runtime.worktreeService.cleanup();
    runtime.appendActivity({
        source: "web",
        status: "info",
        type: "worktree_cleanup",
        threadId: null,
        workspace: runtime.config.workspace,
        actor,
        detail: `${result.removedRecords.length} records removed, ${result.prunedRepositories.length} repos pruned.`,
    });
    return result;
}
export async function relayRuntimeIntegrateSessionWorktrees(runtime, ids, options = {}, actor) {
    const run = runtime.worktreeService.integrate(ids, options);
    runtime.appendActivity({
        source: "web",
        status: run.status === "merged" ? "completed" : run.status === "conflict" ? "failed" : "info",
        type: "worktree_integrated",
        threadId: null,
        workspace: run.worktreePath,
        actor,
        detail: run.status === "merged" ? `Integration branch ${run.branchName} created${run.resolvedConflicts?.length ? ` with ${run.resolvedConflicts.length} resolved conflict(s)` : ""}.` : run.lastError ?? run.status,
    });
    return run;
}
export async function relayRuntimeFinalizeSessionWorktreeIntegration(runtime, id, options = {}, actor) {
    const result = runtime.worktreeService.finalizeIntegration(id, options);
    runtime.appendActivity({
        source: "web",
        status: "completed",
        type: "worktree_integration_finalized",
        threadId: null,
        workspace: result.run.repoRoot,
        actor,
        detail: `Applied ${result.run.branchName} to ${result.run.targetBranch ?? "current branch"} at ${result.run.appliedCommitSha ?? "HEAD"}.`,
    });
    return result;
}
export async function relayRuntimeForkCurrentSessionToWorktree(runtime, options = {}, actor) {
    const session = await runtime.getSession(true);
    runtime.ensureIdle(session);
    const current = runtime.publicInfo(session);
    const external = getExternalSnapshotForSession(session, runtime.config, { maxEvents: 0 });
    if (external?.activity.active && !isExternalSnapshotSuppressedByManagedAbort(external, runtime.activityStore.list({ threadId: external.threadId, limit: 50 }))) {
        throw new Error(`Cannot fork while the external ${external.agentLabel} CLI task is still running.`);
    }
    const fork = runtime.worktreeService.fork({
        agentId: current.agentId,
        contextKey: runtime.contextKey,
        threadId: current.threadId,
        sourceWorkspace: current.workspace,
        includeUncommitted: options.includeUncommitted,
    });
    const info = await session.newThread(fork.record.worktreePath, current.model);
    const record = runtime.worktreeService.linkThread(fork.record.id, info.threadId, info.agentId, runtime.contextKey);
    runtime.updateSession(session);
    runtime.appendActivity({
        source: "web",
        status: "info",
        type: "session_forked_worktree",
        threadId: info.threadId,
        workspace: info.workspace,
        agentId: info.agentId,
        actor,
        detail: `Forked session into ${record.branchName}.`,
    });
    return { session: runtime.publicInfo(session), record, copiedUntrackedFiles: fork.copiedUntrackedFiles, skippedUntrackedFiles: fork.skippedUntrackedFiles, patchApplied: fork.patchApplied };
}
export async function relayRuntimeRemoveSessionWorktree(runtime, id, force, actor) {
    const record = runtime.worktreeService.remove(id, { force });
    runtime.appendActivity({
        source: "web",
        status: "info",
        type: "worktree_removed",
        threadId: record.threadId ?? null,
        workspace: record.worktreePath,
        agentId: record.agentId,
        actor,
        detail: force ? "Removed worktree with force." : "Removed worktree.",
    });
    return record;
}
