import {
  createRiddleProofRunCard
} from "./chunk-FMOYUYH2.js";
import {
  compactRecord,
  isTerminalStatus,
  nonEmptyString,
  recordValue
} from "./chunk-VY4Y5U57.js";

// src/state.ts
var RIDDLE_PROOF_RUN_STATE_VERSION = "riddle-proof.run-state.v1";
function timestamp() {
  return (/* @__PURE__ */ new Date()).toISOString();
}
function createRunId(createdAt) {
  const stamp = createdAt.replace(/\D/g, "").slice(0, 14) || "unknown";
  const entropy = Math.random().toString(36).slice(2, 8) || "run";
  return `rp_${stamp}_${entropy}`;
}
function elapsedMs(start, end) {
  const startMs = start ? Date.parse(start) : NaN;
  const endMs = end ? Date.parse(end) : NaN;
  if (!Number.isFinite(startMs) || !Number.isFinite(endMs)) return void 0;
  return Math.max(0, endMs - startMs);
}
function normalizePrStatus(value) {
  const status = nonEmptyString(value)?.toLowerCase();
  if (status === "merged") return "merged";
  if (status === "open") return "open";
  if (status === "closed") return "closed";
  if (status === "not_found" || status === "not-found") return "not_found";
  if (status === "unavailable") return "unavailable";
  return status || "unknown";
}
function normalizePrLifecycleState(input, checkedAt = timestamp()) {
  const value = recordValue(input);
  if (!value) return void 0;
  const cleanup = recordValue(value.cleanup);
  const mergeCommit = nonEmptyString(value.merge_commit) || nonEmptyString(value.mergeCommit) || nonEmptyString(recordValue(value.mergeCommit)?.oid);
  return compactRecord({
    status: normalizePrStatus(value.status || value.state),
    pr_url: nonEmptyString(value.pr_url) || nonEmptyString(value.prUrl) || nonEmptyString(value.url),
    pr_number: nonEmptyString(value.pr_number) || nonEmptyString(value.prNumber) || (typeof value.number === "number" ? String(value.number) : void 0),
    repo: nonEmptyString(value.repo) || nonEmptyString(value.repository),
    head_branch: nonEmptyString(value.head_branch) || nonEmptyString(value.headBranch) || nonEmptyString(value.headRefName),
    base_branch: nonEmptyString(value.base_branch) || nonEmptyString(value.baseBranch) || nonEmptyString(value.baseRefName),
    merge_commit: mergeCommit,
    merged_at: nonEmptyString(value.merged_at) || nonEmptyString(value.mergedAt),
    closed_at: nonEmptyString(value.closed_at) || nonEmptyString(value.closedAt),
    checked_at: nonEmptyString(value.checked_at) || nonEmptyString(value.checkedAt) || checkedAt,
    source: nonEmptyString(value.source),
    next_action: nonEmptyString(value.next_action) || nonEmptyString(value.nextAction),
    cleanup: cleanup && Object.keys(cleanup).length ? cleanup : void 0
  });
}
function normalizeIntegrationContext(input, fallbackSource) {
  const value = recordValue(input);
  if (!value) {
    return fallbackSource ? { source: fallbackSource } : void 0;
  }
  const metadata = recordValue(value.metadata);
  return compactRecord({
    source: nonEmptyString(value.source) || fallbackSource,
    channel_id: nonEmptyString(value.channel_id),
    thread_id: nonEmptyString(value.thread_id),
    message_id: nonEmptyString(value.message_id),
    source_url: nonEmptyString(value.source_url),
    metadata: metadata && Object.keys(metadata).length ? metadata : void 0
  });
}
function normalizeRunParams(input) {
  return compactRecord({
    repo: input.repo,
    branch: input.branch,
    change_request: input.change_request,
    commit_message: input.commit_message,
    prod_url: input.prod_url,
    capture_script: input.capture_script,
    success_criteria: input.success_criteria,
    assertions: input.assertions,
    verification_mode: input.verification_mode,
    resume_session: input.resume_session,
    target_image_url: input.target_image_url,
    target_image_hash: input.target_image_hash,
    viewport_matrix: input.viewport_matrix,
    deterministic_setup: input.deterministic_setup,
    reference: input.reference,
    base_branch: input.base_branch,
    before_ref: input.before_ref,
    allow_static_preview_fallback: input.allow_static_preview_fallback,
    context: input.context,
    reviewer: input.reviewer,
    mode: input.mode,
    implementation_mode: input.implementation_mode,
    require_diff: input.require_diff,
    allow_code_changes: input.allow_code_changes,
    build_command: input.build_command,
    build_output: input.build_output,
    server_image: input.server_image,
    server_command: input.server_command,
    server_port: input.server_port,
    server_path: input.server_path,
    use_auth: input.use_auth,
    auth_localStorage_json: input.auth_localStorage_json,
    auth_cookies_json: input.auth_cookies_json,
    auth_headers_json: input.auth_headers_json,
    color_scheme: input.color_scheme,
    wait_for_selector: input.wait_for_selector,
    ship_mode: input.ship_mode,
    leave_draft: input.leave_draft,
    engine_state_path: input.engine_state_path,
    harness_state_path: input.harness_state_path,
    riddle_engine_module_url: input.riddle_engine_module_url,
    max_iterations: input.max_iterations,
    auto_approve: input.auto_approve,
    dry_run: input.dry_run,
    integration_context: normalizeIntegrationContext(input.integration_context)
  });
}
function createRunState(input) {
  const createdAt = input.created_at || timestamp();
  return compactRecord({
    version: RIDDLE_PROOF_RUN_STATE_VERSION,
    run_id: input.run_id || createRunId(createdAt),
    state_path: input.state_path,
    worktree_path: input.worktree_path,
    branch: input.branch || input.request.branch,
    current_stage: input.current_stage ?? null,
    stage_started_at: input.stage_started_at ?? null,
    status: input.status || "running",
    created_at: createdAt,
    updated_at: input.updated_at || createdAt,
    request: normalizeRunParams(input.request),
    iterations: input.iterations ?? 0,
    last_checkpoint: input.last_checkpoint ?? null,
    checkpoint_packet: input.checkpoint_packet,
    checkpoint_summary: input.checkpoint_summary,
    state_paths: input.state_paths,
    proof_contract: input.proof_contract,
    run_card: input.run_card,
    checkpoint_history: input.checkpoint_history,
    events: input.events ? [...input.events] : []
  });
}
function appendRunEvent(state, input) {
  const event = {
    ts: input.ts || timestamp(),
    kind: input.kind,
    checkpoint: input.checkpoint,
    stage: input.stage,
    summary: input.summary,
    details: input.details
  };
  state.events.push(compactRecord({
    ts: event.ts,
    kind: event.kind,
    checkpoint: event.checkpoint,
    stage: event.stage,
    summary: event.summary,
    details: event.details
  }));
  if (input.checkpoint !== void 0) state.last_checkpoint = input.checkpoint;
  if (input.stage !== void 0) {
    if (state.current_stage !== input.stage) state.stage_started_at = event.ts;
    state.current_stage = input.stage;
  }
  state.updated_at = event.ts;
  return state;
}
function appendStageHeartbeat(state, input) {
  const at = input.ts || timestamp();
  return appendRunEvent(state, {
    ts: at,
    kind: "stage.heartbeat",
    checkpoint: input.checkpoint || `${input.stage}_heartbeat`,
    stage: input.stage,
    summary: input.summary || `${input.stage} stage is active.`,
    details: compactRecord({
      elapsed_ms: elapsedMs(state.created_at, at),
      stage_elapsed_ms: elapsedMs(state.stage_started_at, at),
      wait_reason: input.wait_reason,
      blocker: input.blocker,
      ...input.details
    })
  });
}
function createRunStatusSnapshot(state, at = timestamp()) {
  const latestEvent = state.events[state.events.length - 1];
  const runId = state.run_id || "unknown";
  return compactRecord({
    run_id: runId,
    status: state.status,
    is_terminal: isTerminalStatus(state.status),
    monitor_should_continue: !isTerminalStatus(state.status),
    current_stage: state.current_stage ?? null,
    state_path: state.state_path ?? null,
    worktree_path: state.worktree_path ?? null,
    branch: state.branch ?? null,
    pr_url: state.pr_url ?? null,
    pr_branch: state.pr_branch ?? null,
    pr_state: state.pr_state,
    ci_status: state.ci_status,
    ship_commit: state.ship_commit,
    ship_remote_head: state.ship_remote_head,
    merge_commit: state.merge_commit,
    merged_at: state.merged_at,
    proof_comment_url: state.proof_comment_url,
    cleanup_report: state.cleanup_report,
    iterations: state.iterations,
    last_checkpoint: state.last_checkpoint ?? null,
    updated_at: state.updated_at,
    elapsed_ms: elapsedMs(state.created_at, at),
    stage_elapsed_ms: elapsedMs(state.stage_started_at, at),
    blocker: state.blocker,
    checkpoint_packet: state.checkpoint_packet,
    checkpoint_summary: state.checkpoint_summary,
    state_paths: state.state_paths,
    proof_contract: state.proof_contract,
    run_card: state.run_card || createRiddleProofRunCard(state, { at }),
    viewport_matrix_status: state.viewport_matrix_status,
    latest_event: latestEvent
  });
}
function setRunStatus(state, status, at = timestamp()) {
  state.status = status;
  state.ok = status !== "blocked" && status !== "failed";
  state.updated_at = at;
  return state;
}
function applyPrLifecycleState(state, input, at = timestamp()) {
  const prState = normalizePrLifecycleState(input, at);
  if (!prState) return state;
  state.pr_state = prState;
  if (prState.pr_url) state.pr_url = prState.pr_url;
  if (prState.head_branch) state.pr_branch = prState.head_branch;
  if (prState.merge_commit) state.merge_commit = prState.merge_commit;
  if (prState.merged_at) state.merged_at = prState.merged_at;
  if (prState.cleanup) state.cleanup_report = prState.cleanup;
  if (prState.status === "merged") {
    state.finalized = true;
    state.status = "completed";
    state.ok = true;
  }
  state.updated_at = at;
  return state;
}

export {
  RIDDLE_PROOF_RUN_STATE_VERSION,
  normalizePrLifecycleState,
  normalizeIntegrationContext,
  normalizeRunParams,
  createRunState,
  appendRunEvent,
  appendStageHeartbeat,
  createRunStatusSnapshot,
  setRunStatus,
  applyPrLifecycleState
};
