/**
 * OpenCode Skills Plugin (Local Version)
 *
 * Implements Anthropic's Agent Skills Specification (v1.0) for OpenCode.
 *
 * Modified to:
 * - Only scan ~/.config/opencode/skills/ directory
 * - Provide minimal logging (one-line summary)
 *
 * Original: https://github.com/malhashemi/opencode-skills
 */
import { tool } from "@opencode-ai/plugin";
import matter from "gray-matter";
import { Glob } from "bun";
import { join, dirname, basename, relative, sep } from "path";
import { z } from "zod";
import os from "os";

const SkillFrontmatterSchema = z.object({
    name: z.string()
        .regex(/^[a-z0-9-]+$/, "Name must be lowercase alphanumeric with hyphens")
        .min(1, "Name cannot be empty"),
    description: z.string()
        .min(20, "Description must be at least 20 characters for discoverability"),
    license: z.string().optional(),
    "allowed-tools": z.array(z.string()).optional(),
    metadata: z.record(z.string()).optional()
});

function generateToolName(skillPath, baseDir) {
    const rel = relative(baseDir, skillPath);
    const dirPath = dirname(rel);
    const components = dirPath.split(sep).filter(c => c !== ".");
    return "skills_" + components.join("_").replace(/-/g, "_");
}

async function parseSkill(skillPath, baseDir) {
    try {
        const content = await Bun.file(skillPath).text();
        const { data, content: markdown } = matter(content);
        
        let frontmatter;
        try {
            frontmatter = SkillFrontmatterSchema.parse(data);
        }
        catch (error) {
            return null;
        }
        
        const skillDir = basename(dirname(skillPath));
        if (frontmatter.name !== skillDir) {
            return null;
        }
        
        const toolName = generateToolName(skillPath, baseDir);
        
        return {
            name: frontmatter.name,
            fullPath: dirname(skillPath),
            toolName,
            description: frontmatter.description,
            allowedTools: frontmatter["allowed-tools"],
            metadata: frontmatter.metadata,
            license: frontmatter.license,
            content: markdown.trim(),
            path: skillPath
        };
    }
    catch (error) {
        return null;
    }
}

async function discoverSkills(basePath) {
    const skills = [];
    
    try {
        const glob = new Glob("**/SKILL.md");
        for await (const match of glob.scan({
            cwd: basePath,
            absolute: true
        })) {
            const skill = await parseSkill(match, basePath);
            if (skill) {
                skills.push(skill);
            }
        }
    }
    catch (error) {
        // Directory doesn't exist, return empty array
    }
    
    return skills;
}

export const SkillsPlugin = async (ctx) => {
    const xdgConfigHome = process.env.XDG_CONFIG_HOME;
    const configSkillsPath = xdgConfigHome
        ? join(xdgConfigHome, "opencode/skills")
        : join(os.homedir(), ".config/opencode/skills");
    
    const skills = await discoverSkills(configSkillsPath);
    
    if (skills.length > 0) {
        console.log(`Skills loaded: ${skills.map(s => s.name).join(", ")}`);
    }
    
    const tools = {};
    for (const skill of skills) {
        tools[skill.toolName] = tool({
            description: skill.description,
            args: {},
            async execute(args, toolCtx) {
                return `# ⚠️ SKILL EXECUTION INSTRUCTIONS ⚠️

**SKILL NAME:** ${skill.name}
**SKILL DIRECTORY:** ${skill.fullPath}/

## EXECUTION WORKFLOW:

**STEP 1: PLAN THE WORK**
Before executing this skill, use the \`todowrite\` tool to create a todo list of the main tasks described in the skill content below.
- Parse the skill instructions carefully
- Identify the key tasks and steps required
- Create todos with status "pending" and appropriate priority levels
- This helps track progress and ensures nothing is missed

**STEP 2: EXECUTE THE SKILL**
Follow the skill instructions below, marking todos as "in_progress" when starting a task and "completed" when done.
Use \`todowrite\` to update task statuses as you work through them.

## PATH RESOLUTION RULES (READ CAREFULLY):

All file paths mentioned below are relative to the SKILL DIRECTORY shown above.

**Examples:**
- If the skill mentions \`scripts/init_skill.py\`, the full path is: \`${skill.fullPath}/scripts/init_skill.py\`
- If the skill mentions \`references/docs.md\`, the full path is: \`${skill.fullPath}/references/docs.md\`
- If the skill mentions \`assets/template.html\`, the full path is: \`${skill.fullPath}/assets/template.html\`

**IMPORTANT:** Always prepend \`${skill.fullPath}/\` to any relative path mentioned in the skill content below.

---

# SKILL CONTENT:

${skill.content}

---

**Remember:** 
1. All relative paths in the skill content above are relative to: \`${skill.fullPath}/\`
2. Update your todo list as you progress through the skill tasks
`;
            }
        });
    }
    
    return { tool: tools };
};
