/**
 * System-prompt assembly helpers for decopilot.
 *
 * dispatch-run.ts is the canonical place where the system-prompt parts are
 * collected (basePrompt, planModePrompt, …, agentPrompt). This module
 * takes that already-ordered, already-filtered array of strings and
 *   (a) wraps each part as an AI-SDK `SystemMessage`,
 *   (b) attaches Anthropic `cacheControl: { ephemeral, 5m }` on the two
 *       cut points so the prefix can be reused across turns, and
 *   (c) appends a per-request, NON-cached `<current-context>` block
 *       carrying the date/time so request-time content never invalidates
 *       the cached prefix.
 *
 * The Anthropic cache markers are namespaced under `providerOptions
 * .anthropic`; non-Anthropic providers ignore the field. OpenRouter
 * specifically reads the same field as a fallback (see
 * `@openrouter/ai-sdk-provider/dist/index.js` getCacheControl) so the
 * markers propagate through OpenRouter routes too.
 */

import { buildCurrentContextPrompt } from "../current-context-prompt";
import { EPHEMERAL_5M } from "./cache-instrumentation";

export { buildCurrentContextPrompt } from "../current-context-prompt";

export interface SystemMessage {
  role: "system";
  content: string;
  providerOptions?: {
    anthropic?: {
      cacheControl?: { type: "ephemeral"; ttl?: "5m" | "1h" };
    };
  };
}

const EPHEMERAL_5M_PROVIDER_OPTIONS = {
  anthropic: { cacheControl: EPHEMERAL_5M },
};

/**
 * Wrap dispatch-run's `string[]` of stable, byte-stable system-prompt
 * parts into AI-SDK system messages, attaching Anthropic cache markers
 * on the two cut points and appending a non-cached current-context tail.
 *
 *   parts:    [p0, p1, …, pN-2, pN-1]
 *   returned: [
 *     { role: "system", content: p0 },                                    // …
 *     { role: "system", content: pN-2, providerOptions: ephemeral_5m },   // ← BP1
 *     { role: "system", content: pN-1, providerOptions: ephemeral_5m },   // ← BP2
 *     { role: "system", content: <current-context> },                     // uncached
 *   ]
 *
 * When `parts` has fewer than 2 items, BP1 collapses (or both BPs
 * collapse if there's only 1). The current-context tail is always
 * appended.
 */
export function buildSystemMessages(
  parts: string[],
  now: Date,
): SystemMessage[] {
  const out: SystemMessage[] = [];
  const bp2Idx = parts.length - 1;
  const bp1Idx = parts.length - 2;
  for (let i = 0; i < parts.length; i++) {
    const isCacheCut = i === bp1Idx || i === bp2Idx;
    out.push({
      role: "system",
      content: parts[i]!,
      ...(isCacheCut ? { providerOptions: EPHEMERAL_5M_PROVIDER_OPTIONS } : {}),
    });
  }
  out.push({
    role: "system",
    content: buildCurrentContextPrompt(now),
  });
  return out;
}
