import type { ToolResult } from "../../provider/canonical.ts";
import type { CompressedResult, ToolResultAdapter } from "./types.ts";
import { jsonCompactLarge } from "./json-compact-large.ts";

export type ContentKind =
  | "json-array"
  | "json-object"
  | "log"
  | "diff"
  | "search-results"
  | "code"
  | "plain-text"
  | "unknown";

const BYTE_THRESHOLD = 4096;
const CLASSIFY_MAX_LEN = 512 * 1024;

function rawContent(r: ToolResult): string {
  return typeof r.content === "string" ? r.content : JSON.stringify(r.content);
}

export function classifyContent(content: string): ContentKind {
  if (content.trim().length === 0) return "unknown";

  try {
    const parsed: unknown = JSON.parse(content);
    return Array.isArray(parsed) ? "json-array" : "json-object";
  } catch {
    // Continue with non-JSON classification.
  }

  const sample = content.length > CLASSIFY_MAX_LEN ? content.slice(0, CLASSIFY_MAX_LEN) : content;

  if (/^diff --git /m.test(sample) || /^@@ /m.test(sample)) {
    return "diff";
  }

  if (/(^|[^A-Za-z0-9_])(ERROR|WARN|Exception|Traceback|failed|timeout)(?=$|[^A-Za-z0-9_])/.test(sample)) {
    return "log";
  }

  if (
    /\bexport\s+function\b/.test(sample) ||
    /\bfunction\b/.test(sample) ||
    /\bclass\b/.test(sample) ||
    /\binterface\b/.test(sample) ||
    /\bimport\s+[^\n]{0,200}?\s+from\b/.test(sample)
  ) {
    return "code";
  }

  return "plain-text";
}

export const contentRouter: ToolResultAdapter = {
  id: "content-router",

  match(r: ToolResult): boolean {
    const raw = rawContent(r);
    const kind = classifyContent(raw);

    return (
      Buffer.byteLength(raw, "utf8") >= BYTE_THRESHOLD &&
      (kind === "json-array" || kind === "json-object") &&
      jsonCompactLarge.match(r)
    );
  },

  compress(r: ToolResult): CompressedResult {
    return jsonCompactLarge.compress(r);
  },
};
