// src/codec/walk.ts
export type StringMapper = (s: string) => string;

export function mapStrings(input: unknown, fn: StringMapper): unknown {
  if (typeof input === "string") return fn(input);
  if (input === null || typeof input !== "object") return input;
  if (Array.isArray(input)) return input.map((v) => mapStrings(v, fn));
  const out: Record<string, unknown> = {};
  for (const k of Object.keys(input as Record<string, unknown>)) {
    out[k] = mapStrings((input as Record<string, unknown>)[k], fn);
  }
  return out;
}

export function mapStringsPreservingThinking(input: unknown, fn: StringMapper): unknown {
  if (typeof input === "string") return fn(input);
  if (input === null || typeof input !== "object") return input;
  if (Array.isArray(input)) return input.map((v) => mapStringsPreservingThinking(v, fn));
  const rec = input as Record<string, unknown>;
  if (rec.type === "thinking" || rec.type === "redacted_thinking") {
    return { ...rec };
  }
  const out: Record<string, unknown> = {};
  for (const k of Object.keys(rec)) {
    out[k] = mapStringsPreservingThinking(rec[k], fn);
  }
  return out;
}
