import { describe, expect, it } from "vitest";
import { sanitizeAssistantErrorMessage } from "../router/assistant-tools/helpers.js";

/**
 * Ticket #53 — AI-tool helpers previously returned `error.message` verbatim
 * for BAD_REQUEST / CONFLICT cases. When the underlying cause was a Prisma
 * error (P2002 unique, P2003 FK, P2025 missing), the text included column
 * names, relation paths, and the offending value — all of which ended up
 * in LLM chat context and, via audit_log.changes, in the DB.
 *
 * `sanitizeAssistantErrorMessage` replaces those patterns with a generic
 * "Invalid input" while letting hand-crafted router messages through.
 */
describe("sanitizeAssistantErrorMessage (#53)", () => {
  it("replaces P2002 unique-constraint leak with generic text", () => {
    const leak =
      "Invalid `prisma.user.create()` invocation in\n/app/src/router/users.ts:142:5\n\nUnique constraint failed on the fields: (`email`)";
    expect(sanitizeAssistantErrorMessage(leak)).toBe("Invalid input");
  });

  it("replaces P2003 FK-violation leak", () => {
    const leak = "Foreign key constraint failed on the field: `clientId`";
    expect(sanitizeAssistantErrorMessage(leak)).toBe("Invalid input");
  });

  it("replaces P2025 missing-record leak", () => {
    const leak =
      "An operation failed because it depends on one or more records that were required but not found.";
    expect(sanitizeAssistantErrorMessage(leak)).toBe("Invalid input");
  });

  it("replaces raw Postgres unique-violation leak", () => {
    const leak =
      'duplicate key value violates unique constraint "User_email_key"\nDETAIL: Key (email)=(alice@example.com) already exists.';
    expect(sanitizeAssistantErrorMessage(leak)).toBe("Invalid input");
  });

  it("replaces raw Postgres not-null leak", () => {
    const leak =
      'null value in column "projectId" of relation "Allocation" violates not-null constraint';
    expect(sanitizeAssistantErrorMessage(leak)).toBe("Invalid input");
  });

  it("replaces raw Postgres check-constraint leak", () => {
    const leak = 'new row for relation "Project" violates check constraint "Project_status_check"';
    expect(sanitizeAssistantErrorMessage(leak)).toBe("Invalid input");
  });

  it("caps excessively long messages (stack-trace dump defence)", () => {
    const giant = "A".repeat(600);
    expect(sanitizeAssistantErrorMessage(giant)).toBe("Invalid input");
  });

  it("handles empty message defensively", () => {
    expect(sanitizeAssistantErrorMessage("")).toBe("Invalid input");
  });

  it("lets short hand-crafted router messages through unchanged", () => {
    const safe = "The project must have a client assigned.";
    expect(sanitizeAssistantErrorMessage(safe)).toBe(safe);
  });

  it("lets business-rule validation text through", () => {
    const safe = "Vacation cannot be approved in its current status.";
    expect(sanitizeAssistantErrorMessage(safe)).toBe(safe);
  });

  it("lets shortCode conflict messages through (quoted value is user-provided)", () => {
    const safe = 'A project with short code "ACME01" already exists.';
    expect(sanitizeAssistantErrorMessage(safe)).toBe(safe);
  });
});
