import assert from "node:assert/strict";
import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { test } from "vitest";

import { discoverAgents } from "../subagent/agents.js";

function makeProject() {
	const project = mkdtempSync(join(tmpdir(), "sf-agent-yaml-"));
	mkdirSync(join(project, ".sf", "agents"), { recursive: true });
	return project;
}

test("discoverAgents_when_project_has_copilot_style_agent_yaml_loads_agent", () => {
	const project = makeProject();
	writeFileSync(
		join(project, ".sf", "agents", "explore.agent.yaml"),
		[
			"name: explore",
			"displayName: Explore Agent",
			"description: >",
			"  Fast codebase exploration in a separate context window.",
			"model: claude-haiku-4.5",
			"tools:",
			"  - grep",
			"  - glob",
			"  - view",
			"promptParts:",
			"  includeAISafety: true",
			"  includeEnvironmentContext: false",
			"prompt: |",
			"  You are an exploration agent.",
			"  Answer quickly and cite exact files.",
			"",
		].join("\n"),
	);

	const { agents, projectAgentsDir } = discoverAgents(project, "project");
	const agent = agents.find((entry) => entry.name === "explore");

	assert.equal(projectAgentsDir, join(project, ".sf", "agents"));
	assert.ok(agent);
	assert.equal(agent.displayName, "Explore Agent");
	assert.equal(
		agent.description,
		"Fast codebase exploration in a separate context window.\n",
	);
	assert.equal(agent.model, "claude-haiku-4.5");
	assert.deepEqual(agent.tools, ["grep", "glob", "view"]);
	assert.deepEqual(agent.promptParts, {
		includeAISafety: true,
		includeEnvironmentContext: false,
	});
	assert.match(agent.systemPrompt, /You are an exploration agent/);
});

test("discoverAgents_when_yaml_tools_wildcard_set_uses_default_full_tool_surface", () => {
	const project = makeProject();
	writeFileSync(
		join(project, ".sf", "agents", "task.agent.yaml"),
		[
			"name: task",
			"description: Execute commands and report results.",
			"tools:",
			'  - "*"',
			"prompt: |",
			"  Execute the requested command once.",
			"",
		].join("\n"),
	);

	const { agents } = discoverAgents(project, "project");
	const agent = agents.find((entry) => entry.name === "task");

	assert.ok(agent);
	assert.equal(agent.tools, undefined);
	assert.match(agent.systemPrompt, /Execute the requested command once/);
});

test("discoverAgents_when_yaml_and_markdown_share_name_prefers_later_project_entry", () => {
	const project = makeProject();
	writeFileSync(
		join(project, ".sf", "agents", "agent-a.md"),
		[
			"---",
			"name: duplicate",
			"description: Markdown definition",
			"---",
			"",
			"Markdown body.",
			"",
		].join("\n"),
	);
	writeFileSync(
		join(project, ".sf", "agents", "agent-z.agent.yaml"),
		[
			"name: duplicate",
			"description: YAML definition",
			"prompt: |",
			"  YAML body.",
			"",
		].join("\n"),
	);

	const { agents } = discoverAgents(project, "project");
	const duplicates = agents.filter((entry) => entry.name === "duplicate");

	assert.equal(duplicates.length, 1);
	assert.equal(duplicates[0].description, "YAML definition");
	assert.match(duplicates[0].systemPrompt, /YAML body/);
});
