import fs from "node:fs";
import os from "node:os";
import path from "node:path";

import { describe, expect, it } from "vitest";

import { removeSkillLocally } from "@/lib/skills/remove-local";

const mkTmpDir = () => fs.mkdtempSync(path.join(os.tmpdir(), "claw3d-skill-remove-"));

describe("skills remove local", () => {
  it("removes a workspace skill directory", () => {
    const workspaceDir = mkTmpDir();
    const managedSkillsDir = mkTmpDir();
    const skillDir = path.join(workspaceDir, "skills", "github");

    fs.mkdirSync(skillDir, { recursive: true });
    fs.writeFileSync(path.join(skillDir, "SKILL.md"), "# skill", "utf8");

    const result = removeSkillLocally({
      skillKey: "github",
      source: "openclaw-workspace",
      baseDir: skillDir,
      workspaceDir,
      managedSkillsDir,
    });

    expect(result).toEqual({
      removed: true,
      removedPath: skillDir,
      source: "openclaw-workspace",
    });
    expect(fs.existsSync(skillDir)).toBe(false);
  });

  it("rejects removal outside the source root", () => {
    const workspaceDir = mkTmpDir();
    const managedSkillsDir = mkTmpDir();
    const outsideDir = mkTmpDir();

    expect(() =>
      removeSkillLocally({
        skillKey: "github",
        source: "openclaw-workspace",
        baseDir: outsideDir,
        workspaceDir,
        managedSkillsDir,
      })
    ).toThrow("Refusing to remove skill outside allowed root");
  });

  it("refuses removing the root skills directory itself", () => {
    const workspaceDir = mkTmpDir();
    const managedSkillsDir = mkTmpDir();
    const workspaceSkillsRoot = path.join(workspaceDir, "skills");
    fs.mkdirSync(workspaceSkillsRoot, { recursive: true });

    expect(() =>
      removeSkillLocally({
        skillKey: "github",
        source: "openclaw-workspace",
        baseDir: workspaceSkillsRoot,
        workspaceDir,
        managedSkillsDir,
      })
    ).toThrow("Refusing to remove the skills root directory");
  });

  it("refuses removing directories that are not skills", () => {
    const workspaceDir = mkTmpDir();
    const managedSkillsDir = mkTmpDir();
    const nonSkillDir = path.join(workspaceDir, "skills", "tmp");
    fs.mkdirSync(nonSkillDir, { recursive: true });

    expect(() =>
      removeSkillLocally({
        skillKey: "tmp",
        source: "openclaw-workspace",
        baseDir: nonSkillDir,
        workspaceDir,
        managedSkillsDir,
      })
    ).toThrow("Refusing to remove non-skill directory");
  });
});
