import { mkdirSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { createExtensionRuntime } from "../src/core/extensions/loader.js";
import type { ResourceLoader } from "../src/core/resource-loader.js";
import { createAgentSession } from "../src/core/sdk.js";
import { SessionManager } from "../src/core/session-manager.js";

describe("createAgentSession skills option", () => {
  let tempDir: string;
  let skillsDir: string;

  beforeEach(() => {
    tempDir = join(
      tmpdir(),
      `pi-sdk-test-${Date.now()}-${Math.random().toString(36).slice(2)}`,
    );
    skillsDir = join(tempDir, "skills", "test-skill");
    mkdirSync(skillsDir, { recursive: true });

    // Create a test skill in the pi skills directory
    writeFileSync(
      join(skillsDir, "SKILL.md"),
      `---
name: test-skill
description: A test skill for SDK tests.
---

# Test Skill

This is a test skill.
`,
    );
  });

  afterEach(() => {
    if (tempDir) {
      rmSync(tempDir, { recursive: true, force: true });
    }
  });

  it("should discover skills by default and expose them on session.skills", async () => {
    const { session } = await createAgentSession({
      cwd: tempDir,
      agentDir: tempDir,
      sessionManager: SessionManager.inMemory(),
    });

    // Skills should be discovered and exposed on the session
    expect(session.resourceLoader.getSkills().skills.length).toBeGreaterThan(0);
    expect(
      session.resourceLoader
        .getSkills()
        .skills.some((s) => s.name === "test-skill"),
    ).toBe(true);
  });

  it("should have empty skills when resource loader returns none (--no-skills)", async () => {
    const resourceLoader: ResourceLoader = {
      getExtensions: () => ({
        extensions: [],
        errors: [],
        runtime: createExtensionRuntime(),
      }),
      getSkills: () => ({ skills: [], diagnostics: [] }),
      getPrompts: () => ({ prompts: [], diagnostics: [] }),
      getThemes: () => ({ themes: [], diagnostics: [] }),
      getAgentsFiles: () => ({ agentsFiles: [] }),
      getSystemPrompt: () => undefined,
      getAppendSystemPrompt: () => [],
      getPathMetadata: () => new Map(),
      extendResources: () => {},
      reload: async () => {},
    };

    const { session } = await createAgentSession({
      cwd: tempDir,
      agentDir: tempDir,
      sessionManager: SessionManager.inMemory(),
      resourceLoader,
    });

    expect(session.resourceLoader.getSkills().skills).toEqual([]);
    expect(session.resourceLoader.getSkills().diagnostics).toEqual([]);
  });

  it("should use provided skills when resource loader supplies them", async () => {
    const customSkill = {
      name: "custom-skill",
      description: "A custom skill",
      filePath: "/fake/path/SKILL.md",
      baseDir: "/fake/path",
      source: "custom" as const,
      disableModelInvocation: false,
    };

    const resourceLoader: ResourceLoader = {
      getExtensions: () => ({
        extensions: [],
        errors: [],
        runtime: createExtensionRuntime(),
      }),
      getSkills: () => ({ skills: [customSkill], diagnostics: [] }),
      getPrompts: () => ({ prompts: [], diagnostics: [] }),
      getThemes: () => ({ themes: [], diagnostics: [] }),
      getAgentsFiles: () => ({ agentsFiles: [] }),
      getSystemPrompt: () => undefined,
      getAppendSystemPrompt: () => [],
      getPathMetadata: () => new Map(),
      extendResources: () => {},
      reload: async () => {},
    };

    const { session } = await createAgentSession({
      cwd: tempDir,
      agentDir: tempDir,
      sessionManager: SessionManager.inMemory(),
      resourceLoader,
    });

    expect(session.resourceLoader.getSkills().skills).toEqual([customSkill]);
    expect(session.resourceLoader.getSkills().diagnostics).toEqual([]);
  });
});
