// Integration tests for Phase 29: default-provider
// Covers: adapter probe logic, Hermes promptTemplate contract, default agent instructions bundle

import { describe, it, expect } from "vitest";
import { findServerAdapter } from "../adapters/index.js";
import {
  loadDefaultAgentInstructionsBundle,
  resolveDefaultAgentInstructionsBundleRole,
} from "../services/default-agent-instructions.js";

// ---------------------------------------------------------------------------
// The same hermesPromptTemplate constructed in NexusOnboardingWizard.
// Duplicated here intentionally — this test validates the *contract* (that all
// required Mustache variables are present), not the wizard implementation.
// ---------------------------------------------------------------------------
const APP_NAME = "Nexus"; // VOCAB.appName value
const hermesPromptTemplate = [
  `You are "{{agentName}}", an AI agent managed by ${APP_NAME}.`,
  "",
  "Your identity:",
  "  Agent ID: {{agentId}}",
  "  Company ID: {{companyId}}",
  "  API Base: {{paperclipApiUrl}}",
  "  Run ID: {{runId}}",
  "",
  "IMPORTANT: Use the `terminal` tool with `curl` for ALL API calls.",
  'IMPORTANT: Always include `-H "X-Paperclip-Run-Id: {{runId}}"` on API calls that modify data.',
  "",
  "Before starting any task:",
  "1. Call `GET {{paperclipApiUrl}}/api/agents/me` to retrieve your managed instructions",
  "2. Follow the HEARTBEAT.md workflow from your instructions",
  "3. Use TOOLS.md for available API endpoints",
  "",
  "{{#taskId}}",
  "Assigned task: {{taskId}} - {{taskTitle}}",
  "{{/taskId}}",
].join("\n");

// ---------------------------------------------------------------------------
// Test group 1: Adapter probe route logic
// ---------------------------------------------------------------------------

describe("adapter probe route logic", () => {
  it("findServerAdapter returns hermes_local adapter with testEnvironment", () => {
    const adapter = findServerAdapter("hermes_local");
    expect(adapter).not.toBeNull();
    expect(adapter?.type).toBe("hermes_local");
    expect(typeof adapter?.testEnvironment).toBe("function");
  });

  it("hermes testEnvironment handles missing CLI gracefully", async () => {
    const adapter = findServerAdapter("hermes_local");
    expect(adapter?.testEnvironment).toBeDefined();

    const result = await adapter!.testEnvironment!({
      companyId: "",
      adapterType: "hermes_local",
      config: {},
    });

    // Result should always have a status and checks array
    expect(typeof result.status).toBe("string");
    expect(Array.isArray(result.checks)).toBe(true);

    // If hermes CLI is not installed in CI, there should be an error check
    // with a code containing "not_found" or "cli".
    // If it IS installed, the checks should pass — either is acceptable.
    const hasCliError = result.checks.some(
      (c: { level: string; code?: string }) =>
        c.level === "error" &&
        (c.code?.includes("not_found") || c.code?.includes("cli"))
    );
    const isAvailable = result.status === "ok" || result.status === "pass";

    // Either CLI is available (no error checks) or not available (has error checks)
    expect(hasCliError || isAvailable).toBe(true);
  });
});

// ---------------------------------------------------------------------------
// Test group 2: Hermes promptTemplate construction
// ---------------------------------------------------------------------------

describe("hermes promptTemplate construction", () => {
  it("hermes promptTemplate contains required Mustache variables", () => {
    expect(hermesPromptTemplate).toContain("{{agentName}}");
    expect(hermesPromptTemplate).toContain("{{agentId}}");
    expect(hermesPromptTemplate).toContain("{{companyId}}");
    expect(hermesPromptTemplate).toContain("{{paperclipApiUrl}}");
    expect(hermesPromptTemplate).toContain("{{runId}}");
    expect(hermesPromptTemplate).toContain("{{taskId}}");
    expect(hermesPromptTemplate).toContain("{{taskTitle}}");
  });

  it("hermes promptTemplate instructs agent to call /api/agents/me", () => {
    expect(hermesPromptTemplate).toContain("agents/me");
  });

  it("hermes promptTemplate mentions HEARTBEAT.md workflow", () => {
    expect(hermesPromptTemplate).toContain("HEARTBEAT.md");
  });
});

// ---------------------------------------------------------------------------
// Test group 3: Default agent instructions bundle (DFLT-03)
// ---------------------------------------------------------------------------

describe("default agent instructions bundle", () => {
  it("loadDefaultAgentInstructionsBundle loads ceo bundle with all 4 files", async () => {
    const bundle = await loadDefaultAgentInstructionsBundle("ceo");
    expect(Object.keys(bundle)).toContain("AGENTS.md");
    expect(Object.keys(bundle)).toContain("HEARTBEAT.md");
    expect(Object.keys(bundle)).toContain("SOUL.md");
    expect(Object.keys(bundle)).toContain("TOOLS.md");
    expect(bundle["HEARTBEAT.md"].length).toBeGreaterThan(0);
  });

  it("loadDefaultAgentInstructionsBundle loads engineer bundle with all 4 files", async () => {
    const bundle = await loadDefaultAgentInstructionsBundle("engineer");
    expect(Object.keys(bundle)).toContain("AGENTS.md");
    expect(Object.keys(bundle)).toContain("HEARTBEAT.md");
    expect(Object.keys(bundle)).toContain("SOUL.md");
    expect(Object.keys(bundle)).toContain("TOOLS.md");
    expect(bundle["HEARTBEAT.md"].length).toBeGreaterThan(0);
  });

  it("resolveDefaultAgentInstructionsBundleRole maps known roles correctly", () => {
    expect(resolveDefaultAgentInstructionsBundleRole("ceo")).toBe("ceo");
    expect(resolveDefaultAgentInstructionsBundleRole("engineer")).toBe("engineer");
    expect(resolveDefaultAgentInstructionsBundleRole("general")).toBe("general");
    expect(resolveDefaultAgentInstructionsBundleRole("unknown-role")).toBe("default");
    expect(resolveDefaultAgentInstructionsBundleRole("")).toBe("default");
  });
});
