/**
 * BrainPort contract test suite.
 *
 * Forge adapters (PostgresBrainAdapter) run this suite to validate
 * semantic correctness, not just type conformance.
 *
 * Usage in Forge:
 * ```typescript
 * import { brainPortContract } from "@vauban-org/agent-sdk/testing/contracts";
 * brainPortContract(async () => {
 *   const port = new PostgresBrainAdapter(testPool);
 *   return { port, cleanup: () => testPool.end() };
 * });
 * ```
 *
 * @public
 */

import { describe, it, expect, beforeAll, afterAll } from "vitest";
import type { BrainPort } from "../../ports/brain.js";

export function brainPortContract(
  factory: () => Promise<{ port: BrainPort; cleanup(): Promise<void> }>
): void {
  let port: BrainPort;
  let cleanup: () => Promise<void>;

  beforeAll(async () => {
    const result = await factory();
    port = result.port;
    cleanup = result.cleanup;
  });

  afterAll(async () => {
    await cleanup();
  });

  describe("BrainPort contract", () => {
    it("archives and retrieves knowledge", async () => {
      const entry = await port.archiveKnowledge({
        content: "Test knowledge entry for contract validation",
        category: "forge_test",
        tags: ["test", "contract"],
        confidence: 0.9,
      });
      expect(entry).not.toBeNull();
      expect(entry!.id).toBeDefined();
      expect(entry!.content).toContain("contract validation");
    });

    it("queries by category", async () => {
      if (!port.queryKnowledge) return; // optional

      await port.archiveKnowledge({
        content: "Category-specific entry",
        category: "forge_test_category",
        tags: ["test"],
      });

      const results = await port.queryKnowledge("Category", {
        category: "forge_test_category",
        limit: 5,
      });
      expect(results.length).toBeGreaterThan(0);
      expect(results[0].category).toBe("forge_test_category");
    });

    it("returns null for non-existent queries", async () => {
      if (!port.queryKnowledge) return;

      const results = await port.queryKnowledge("nonexistent_xyz_123", { limit: 1 });
      expect(results.length).toBe(0);
    });

    it("supports working memory tier", async () => {
      if (!port.working) return;

      await port.working.set("test-run", "key1", { value: 42 });
      const result = await port.working.get("test-run", "key1");
      expect(result).toEqual({ value: 42 });
    });

    it("supports episodic memory tier", async () => {
      if (!port.episodic) return;

      await port.episodic.record("test-agent", "run-1", "cycle_completed", { cycles: 5 });
      const events = await port.episodic.since("test-agent", Date.now() - 60_000);
      expect(events.length).toBeGreaterThan(0);
    });
  });
}
