import { describe, expect, it } from "vitest";
import {
  resolveAdapterSkillConfig,
  listAdapterSkillConfigs,
} from "@paperclipai/adapter-utils";

// ADAPT-01: resolveAdapterSkillConfig exists and returns AdapterSkillConfig for any string input
describe("resolveAdapterSkillConfig", () => {
  // ADAPT-02: claude_local
  it("returns correct config for claude_local", () => {
    const cfg = resolveAdapterSkillConfig("claude_local");
    expect(cfg.adapterType).toBe("claude_local");
    expect(cfg.skillDir).toBe("~/.claude/skills/");
    expect(cfg.format).toBe("skill-md");
    expect(cfg.supportsInstall).toBe(true);
    expect(cfg.unsupportedReason).toBeNull();
  });

  // ADAPT-03: hermes_local
  it("returns correct config for hermes_local", () => {
    const cfg = resolveAdapterSkillConfig("hermes_local");
    expect(cfg.adapterType).toBe("hermes_local");
    expect(cfg.skillDir).toBe("~/.hermes/skills/");
    expect(cfg.nativeSkillDir).toBe("~/.hermes/skills/");
    expect(cfg.supportsInstall).toBe(true);
    expect(cfg.unsupportedReason).toBeNull();
  });

  // ADAPT-04: openclaw_gateway
  it("returns correct config for openclaw_gateway", () => {
    const cfg = resolveAdapterSkillConfig("openclaw_gateway");
    expect(cfg.adapterType).toBe("openclaw_gateway");
    expect(cfg.skillDir).toBe("~/.openclaw/skills/");
    expect(cfg.format).toBe("skill-md");
    expect(cfg.supportsInstall).toBe(true);
    expect(cfg.unsupportedReason).toBeNull();
  });

  // ADAPT-05: codex_local
  it("returns correct config for codex_local", () => {
    const cfg = resolveAdapterSkillConfig("codex_local");
    expect(cfg.adapterType).toBe("codex_local");
    expect(cfg.skillDir).toBe("~/.agents/skills/");
    expect(cfg.format).toBe("skill-md");
    expect(cfg.supportsInstall).toBe(true);
    expect(cfg.unsupportedReason).toBeNull();
  });

  // ADAPT-06: cursor
  it("returns correct config for cursor", () => {
    const cfg = resolveAdapterSkillConfig("cursor");
    expect(cfg.adapterType).toBe("cursor");
    expect(cfg.skillDir).toBe("~/.cursor/skills/");
    expect(cfg.format).toBe("skill-md");
    expect(cfg.supportsInstall).toBe(true);
    expect(cfg.unsupportedReason).toBeNull();
  });

  // ADAPT-07: opencode_local
  it("returns correct config for opencode_local", () => {
    const cfg = resolveAdapterSkillConfig("opencode_local");
    expect(cfg.adapterType).toBe("opencode_local");
    expect(cfg.skillDir).toBe("~/.config/opencode/skills/");
    expect(cfg.format).toBe("skill-md");
    expect(cfg.supportsInstall).toBe(true);
    expect(cfg.unsupportedReason).toBeNull();
  });

  // ADAPT-08: pi_local and gemini_local
  it("returns correct config for pi_local", () => {
    const cfg = resolveAdapterSkillConfig("pi_local");
    expect(cfg.adapterType).toBe("pi_local");
    expect(cfg.skillDir).toBe("~/.pi/agent/skills/");
    expect(cfg.format).toBe("skill-md");
    expect(cfg.supportsInstall).toBe(true);
  });

  it("returns correct config for gemini_local", () => {
    const cfg = resolveAdapterSkillConfig("gemini_local");
    expect(cfg.adapterType).toBe("gemini_local");
    expect(cfg.skillDir).toBe("~/.gemini/skills/");
    expect(cfg.format).toBe("skill-md");
    expect(cfg.supportsInstall).toBe(true);
  });

  // ADAPT-09: process and http — no skills supported
  it("returns unsupported config for process adapter", () => {
    const cfg = resolveAdapterSkillConfig("process");
    expect(cfg.adapterType).toBe("process");
    expect(cfg.skillDir).toBeNull();
    expect(cfg.format).toBe("none");
    expect(cfg.supportsInstall).toBe(false);
    expect(cfg.unsupportedReason).toBeTruthy();
  });

  it("returns unsupported config for http adapter", () => {
    const cfg = resolveAdapterSkillConfig("http");
    expect(cfg.adapterType).toBe("http");
    expect(cfg.skillDir).toBeNull();
    expect(cfg.format).toBe("none");
    expect(cfg.supportsInstall).toBe(false);
    expect(cfg.unsupportedReason).toBeTruthy();
  });

  // ADAPT-10: unknown adapter type returns fallback, does not throw
  it("returns fallback config for unknown adapter type without throwing", () => {
    const cfg = resolveAdapterSkillConfig("totally_unknown_adapter");
    expect(cfg.adapterType).toBe("totally_unknown_adapter");
    expect(cfg.supportsInstall).toBe(false);
    expect(cfg.format).toBe("none");
    // should not throw — just a safe fallback
  });

  it("populates adapterType field for unknown adapter types", () => {
    const cfg = resolveAdapterSkillConfig("some_future_adapter");
    expect(cfg.adapterType).toBe("some_future_adapter");
  });
});

// listAdapterSkillConfigs returns all 10 registered configs
describe("listAdapterSkillConfigs", () => {
  it("returns an array of all 10 registered adapter configs", () => {
    const configs = listAdapterSkillConfigs();
    expect(configs).toHaveLength(10);
  });

  it("contains entries for all expected adapter types", () => {
    const configs = listAdapterSkillConfigs();
    const types = configs.map((c) => c.adapterType);
    expect(types).toContain("claude_local");
    expect(types).toContain("hermes_local");
    expect(types).toContain("openclaw_gateway");
    expect(types).toContain("codex_local");
    expect(types).toContain("cursor");
    expect(types).toContain("opencode_local");
    expect(types).toContain("pi_local");
    expect(types).toContain("gemini_local");
    expect(types).toContain("process");
    expect(types).toContain("http");
  });

  it("has no TBD or empty stub entries — all configs are fully populated", () => {
    const configs = listAdapterSkillConfigs();
    for (const cfg of configs) {
      expect(cfg.adapterType).toBeTruthy();
      expect(cfg.format).toMatch(/^(skill-md|none)$/);
      if (cfg.supportsInstall) {
        expect(cfg.skillDir).toBeTruthy();
      } else {
        expect(cfg.skillDir).toBeNull();
      }
    }
  });
});
