#!/usr/bin/env node
/**
 * Agent Runtime CLI — PR-35
 *
 * Usage:
 *   echo '{"task":{...},"context":{...}}' | node scripts/runtime.mjs
 *
 * stdin:
 *   { task, context: { baselineData?, candidateData?, ... }, options? }
 *
 * Output: JSON { success, taskResult, report }
 * Exit: 0=passed, 1=failed/blocked/error
 */

import { readFileSync } from "node:fs";
import { createTask, createExecutionPlan } from "../src/agent-runtime/domain.mjs";
import { executePipeline, recoverTask } from "../src/agent-runtime/pipeline.mjs";
import { createRuntimeContext, autoGateAdapter, createCertificationAdapter } from "../src/agent-runtime/adapters.mjs";
import { generateRuntimeReport } from "../src/agent-runtime/reporting.mjs";

function readStdin() {
  try {
    const raw = readFileSync(0, "utf8").trim();
    return raw ? JSON.parse(raw) : null;
  } catch (e) {
    return { _error: `Parse error: ${e.message}` };
  }
}

function main() {
  const input = readStdin();
  if (!input) { console.error("Error: No stdin input."); process.exit(1); }
  if (input._error) { console.error(input._error); process.exit(1); }

  const { task: rawTask, context: rawCtx = {}, options = {}, action = "execute" } = input;
  if (!rawTask) { console.error("Error: 'task' field required."); process.exit(1); }

  // 反序列化 Task
  const task = createTask({
    id: rawTask.id, title: rawTask.title || rawTask.id,
    description: rawTask.description, tags: rawTask.tags,
    dependsOn: rawTask.dependsOn, parentTaskId: rawTask.parentTaskId,
    metadata: rawTask.metadata,
  });
  task.executionPlan = createExecutionPlan({
    taskId: task.id,
    steps: (rawTask.steps || []).map(s => ({
      id: s.id, name: s.name || s.id, action: s.action || s.name,
      dependsOn: s.dependsOn, expectedArtifacts: s.expectedArtifacts, metadata: s.metadata,
    })),
    strategy: rawTask.strategy,
  });
  task.maxRetries = rawTask.maxRetries ?? 3;

  // 构建 Runtime Context
  const rctx = createRuntimeContext({
    checklistAdapter: rawCtx.checklist ? (ctx) => ({ status: rawCtx.checklist === "pass" ? "pass" : "fail", blockers: [], warnings: [], confidence: 100 }) : null,
    baselineAdapter: rawCtx.baseline ? (_ctx, b, c) => ({ status: "pass", changes: [], blockers: [], warnings: [] }) : null,
    gateAdapter: rawCtx.gate ? autoGateAdapter : null,
    certificationAdapter: createCertificationAdapter(),
    baselineData: rawCtx.baselineData || null,
    candidateData: rawCtx.candidateData || null,
    pipelineOptions: options,
  });

  try {
    let taskResult;
    if (action === "recover") {
      task.state = "failed";
      task.retryCount = rawTask.retryCount || 0;
      taskResult = recoverTask(task, rctx, options);
    } else {
      taskResult = executePipeline(task, rctx, options);
    }

    const report = generateRuntimeReport(task, taskResult);
    const output = { success: taskResult.status === "passed", taskResult, report };
    console.log(JSON.stringify(output, null, 2));
    process.exit(taskResult.status === "passed" ? 0 : 1);
  } catch (e) {
    console.error(`Runtime error: ${e.message}`);
    process.exit(1);
  }
}

main();
