import { describe, expect, it } from "vitest";
import type { PaperclipPluginManifestV1 } from "@paperclipai/shared";
import { createTestHarness } from "@paperclipai/plugin-sdk/testing";

describe("plugin SDK test harness", () => {
  it("returns scoped execution workspace metadata with the read capability", async () => {
    const manifest: PaperclipPluginManifestV1 = {
      id: "paperclip.test-execution-workspace-metadata",
      apiVersion: 1,
      version: "0.1.0",
      displayName: "Execution Workspace Metadata",
      description: "Test plugin",
      author: "Paperclip",
      categories: ["automation"],
      capabilities: ["execution.workspaces.read"],
      entrypoints: { worker: "./dist/worker.js" },
    };
    const harness = createTestHarness({ manifest });
    harness.seed({
      executionWorkspaces: [{
        id: "workspace-1",
        companyId: "company-1",
        projectId: "project-1",
        projectWorkspaceId: "project-workspace-1",
        path: "/tmp/paperclip-test",
        cwd: "/tmp/paperclip-test",
        repoUrl: "https://example.com/repo.git",
        baseRef: "main",
        branchName: "feature/test",
        providerType: "git_worktree",
        providerMetadata: { sandboxId: "sandbox-1" },
      }],
    });

    await expect(harness.ctx.executionWorkspaces.get("workspace-1", "company-1")).resolves.toMatchObject({
      id: "workspace-1",
      cwd: "/tmp/paperclip-test",
      branchName: "feature/test",
      providerMetadata: { sandboxId: "sandbox-1" },
    });
    await expect(harness.ctx.executionWorkspaces.get("workspace-1", "company-2")).resolves.toBeNull();
  });

  it("requires execution.workspaces.read before returning workspace metadata", async () => {
    const manifest: PaperclipPluginManifestV1 = {
      id: "paperclip.test-missing-execution-workspace-read",
      apiVersion: 1,
      version: "0.1.0",
      displayName: "Missing Workspace Read Capability",
      description: "Test plugin",
      author: "Paperclip",
      categories: ["automation"],
      capabilities: [],
      entrypoints: { worker: "./dist/worker.js" },
    };
    const harness = createTestHarness({ manifest });

    await expect(harness.ctx.executionWorkspaces.get("workspace-1", "company-1")).rejects.toThrow(
      "missing required capability 'execution.workspaces.read'",
    );
  });

  it("requires skills.managed capability before resetting a missing declaration", async () => {
    const manifest: PaperclipPluginManifestV1 = {
      id: "paperclip.test-missing-managed-skill-capability",
      apiVersion: 1,
      version: "0.1.0",
      displayName: "Missing Managed Skill Capability",
      description: "Test plugin",
      author: "Paperclip",
      categories: ["automation"],
      capabilities: [],
      entrypoints: { worker: "./dist/worker.js" },
      skills: [{
        skillKey: "wiki-maintainer",
        displayName: "Wiki Maintainer",
      }],
    };
    const harness = createTestHarness({ manifest });

    await expect(harness.ctx.skills.managed.reset("unknown-skill", "company-1")).rejects.toThrow(
      "missing required capability 'skills.managed'",
    );
  });

  it("requires access and authorization capabilities for permission SDK calls", async () => {
    const manifest: PaperclipPluginManifestV1 = {
      id: "paperclip.test-missing-access-authz-capability",
      apiVersion: 1,
      version: "0.1.0",
      displayName: "Missing Access Capability",
      description: "Test plugin",
      author: "Paperclip",
      categories: ["automation"],
      capabilities: [],
      entrypoints: { worker: "./dist/worker.js" },
    };
    const harness = createTestHarness({ manifest });

    await expect(harness.ctx.access.members.list({ companyId: "company-1" })).rejects.toThrow(
      "missing required capability 'access.members.read'",
    );
    await expect(harness.ctx.authorization.grants.list({ companyId: "company-1" })).rejects.toThrow(
      "missing required capability 'authorization.grants.read'",
    );
    await expect(harness.ctx.authorization.audit.search({ companyId: "company-1" })).rejects.toThrow(
      "missing required capability 'authorization.audit.read'",
    );
  });
});
