/*
 * self-edit-langs.js — display half of the self-modification tools
 * (edit_source / edit_playbook / edit_settings), the counterpart to
 * run-langs.js. Nothing executes or applies here: by the time this parses a
 * fence, the write (if any) already happened on the backend under the user's
 * per-call approval, in synapse/self_edit.py. This side only labels and lays
 * out what was returned.
 *
 * One fence tag, three payload shapes (source / playbook / settings), because
 * all three go through the same approval round-trip and the same "carry what
 * happened in one block" idea as run_snippet's nexus-run fence.
 */

export const EDIT_FENCE_LANG = "nexus-edit";

/**
 * Parse a nexus-edit fence body. Returns null for anything malformed or of an
 * unrecognized kind — the caller falls back to showing the block as plain
 * code, the same honest-fallback behavior as parseRunResult.
 */
export function parseEditResult(text) {
  let data;
  try {
    data = JSON.parse(text);
  } catch {
    return null;
  }
  if (!data || typeof data !== "object") return null;

  if (data.kind === "source") {
    if (typeof data.path !== "string" || typeof data.diff !== "string") return null;
    return {
      kind: "source",
      path: data.path,
      diff: data.diff,
      commit: typeof data.commit === "string" ? data.commit : null,
      instruction: typeof data.instruction === "string" ? data.instruction : "",
    };
  }

  if (data.kind === "playbook") {
    if (typeof data.id !== "string") return null;
    return {
      kind: "playbook",
      id: data.id,
      title: typeof data.title === "string" ? data.title : "",
      goal: typeof data.goal === "string" ? data.goal : "",
      instructions: typeof data.instructions === "string" ? data.instructions : "",
      isMainPlaybook: !!data.is_main_playbook,
    };
  }

  if (data.kind === "settings") {
    if (!data.applied || typeof data.applied !== "object") return null;
    return {
      kind: "settings",
      applied: data.applied,
      ignoredUnknown: Array.isArray(data.ignored_unknown) ? data.ignored_unknown : [],
      policyChange: !!data.policy_change,
      systemPromptChange: !!data.system_prompt_change,
    };
  }

  return null;
}
