import {
  booleanField,
  normalizeWhitespace,
  stringField,
  truncateText,
} from "@best-agent/foundation";
import type { ThreadEvidenceRecord } from "@best-agent/protocol";
import { readsSensitiveShellCommand } from "../../policy/runtime-policy.js";

export function extractShellCommandFromEvidence(
  record: ThreadEvidenceRecord,
  mode: "display" | "evaluation" | "provider" = "evaluation",
): string | undefined {
  if (mode === "evaluation") {
    return (
      stringField(record.payload, "commandForEvaluation") ??
      stringField(record.payload, "evaluationCommand") ??
      stringField(record.payload, "command")
    );
  }
  if (mode === "provider") {
    return stringField(record.payload, "commandForProvider");
  }
  return (
    stringField(record.payload, "commandDisplay") ??
    stringField(record.payload, "commandForProvider") ??
    stringField(record.payload, "command")
  );
}

export function isSensitiveShellEvidence(record: ThreadEvidenceRecord): boolean {
  if (stringField(record.payload, "sensitivity") === "sensitive-redacted") {
    return true;
  }
  if (booleanField(record.payload, "indexable") === false) {
    return true;
  }
  const command = extractShellCommandFromEvidence(record, "evaluation");
  return command ? readsSensitiveShellCommand(command) : false;
}

export function summarizeShellEvidence(record: ThreadEvidenceRecord): string {
  const command = extractShellCommandFromEvidence(record, "display") ?? record.summary;
  const outcome = stringField(record.payload, "outcome") ?? "unknown";
  const output = extractRedactedShellOutput(record);
  return [
    `- Shell ${outcome}: ${truncateForReasoning(command)}`,
    output ? `  ${truncateForReasoning(output)}` : undefined,
  ]
    .filter((line): line is string => Boolean(line))
    .join("\n");
}

function extractRedactedShellOutput(record: ThreadEvidenceRecord): string {
  const candidates = [
    stringField(record.payload, "outputPreview"),
    stringField(record.payload, "stdoutSummary"),
    stringField(record.payload, "stderrSummary"),
  ].filter((value): value is string => Boolean(value?.trim()));
  return candidates.join("\n");
}

function truncateForReasoning(value: string): string {
  return truncateText(normalizeWhitespace(value), 240);
}
