/**
 * prefix.ts — Phase 2: split the provider payload's system message into
 * stable (cacheable) and variable (project/session) parts.
 *
 * Ground truth (findings §3, Phase 2 corrections):
 *   The `developer` message content renders as:
 *     [stable sections 1–5] [optional <project_context>] [cwd line]
 *   The `# Tools …</tools>…` block is NOT in this string — it is rendered
 *   by the template from the payload `tools[]` array, AFTER the cwd line.
 *
 * Boundaries (measured):
 *   - `<project_context>` block is ABSENT when the project has no AGENTS.md.
 *   - Separator newlines before the variable section differ per project
 *     (projA: \n\n, projB: \n\n\n), so the stable content is taken up to
 *     the earliest boundary marker and trailing whitespace is stripped.
 */

export interface StablePrefix {
  /** Stable content (sections 1–5), trailing whitespace stripped. */
  text: string;
  /** Which boundary ended the stable region. */
  boundary: "project_context" | "cwd" | null;
  /** Index of the boundary marker in the original content. */
  boundaryIndex: number;
  ok: boolean;
  reason?: string;
}

const PC_MARKER = "\n<project_context>";
/** pi < 0.87: plain-text cwd line at the end of the system prompt. */
const CWD_MARKER = "\nCurrent working directory: ";
/** pi >= 0.87: sectioned prompt — the cwd section is `<cwd>\n<path>\n</cwd>`.
 *  The plain-text marker was removed; use whichever boundary is present. */
const CWD_SECTION_MARKER = "\n<cwd>";

export function extractStablePrefix(content: string): StablePrefix {
  const iPc = content.indexOf(PC_MARKER);
  const iCwdA = content.indexOf(CWD_MARKER);
  const iCwdB = content.indexOf(CWD_SECTION_MARKER);
  let iCwd = -1;
  if (iCwdA !== -1 && iCwdB !== -1) iCwd = Math.min(iCwdA, iCwdB);
  else iCwd = iCwdA !== -1 ? iCwdA : iCwdB;

  let idx = -1;
  let boundary: StablePrefix["boundary"] = null;
  if (iPc !== -1 && (iCwd === -1 || iPc < iCwd)) {
    idx = iPc;
    boundary = "project_context";
  } else if (iCwd !== -1) {
    idx = iCwd;
    boundary = "cwd";
  }

  if (idx === -1) {
    return {
      text: "",
      boundary: null,
      boundaryIndex: -1,
      ok: false,
      reason: "no variable-section marker found in system content",
    };
  }

  return {
    text: content.slice(0, idx).replace(/\s+$/, ""),
    boundary,
    boundaryIndex: idx,
    ok: true,
  };
}

/**
 * Find the system message in a provider payload.
 * Pi currently uses role "developer"; "system" kept for robustness.
 */
export function findSystemMessage(
  messages: Array<{ role?: string; content?: unknown }>,
): { role: string; content: string } | null {
  for (const m of messages) {
    if ((m.role === "developer" || m.role === "system") && typeof m.content === "string") {
      return { role: m.role, content: m.content };
    }
  }
  return null;
}
