/**
 * githubSkillTools.ts — MCP tools for GitHub agent skill discovery and import.
 *
 * Provides tools to:
 *   - Search GitHub for repos with SKILL.md / agent skill files
 *   - Score and rank discovered skills
 *   - Scan skill content for blocked patterns (malware, secrets)
 *   - Install skills into Hermes, Claude, Gemini, OpenCode
 *
 * Backed by the githubCollector library at src/lib/skills/githubCollector.ts.
 */

import { z } from "zod";
import { sanitizeErrorMessage } from "../../utils/error.ts";
import {
  searchGitHubSkills,
  scanText,
  resolveInstallPath,
  GitHubSkillsSearchSchema,
  GitHubSkillsScanSchema,
  GitHubSkillsInstallSchema,
  INSTALL_TARGETS,
  type GitHubSkillRepo,
  type SkillInstallResult,
} from "@/lib/skills/githubCollector";

// ── Handlers ─────────────────────────────────────────────────────────────────

async function handleSearch(args: z.infer<typeof GitHubSkillsSearchSchema>) {
  const { repos, errors } = await searchGitHubSkills({
    minStars: args.minStars,
    maxResults: args.maxResults,
  });

  let filtered = repos;
  if (args.minScore > 0) filtered = filtered.filter((r) => r.score >= args.minScore);
  if (args.query) {
    const q = args.query.toLowerCase();
    filtered = filtered.filter(
      (r) => r.fullName.toLowerCase().includes(q) || r.description.toLowerCase().includes(q)
    );
  }

  return {
    skills: filtered.map((r: GitHubSkillRepo) => ({
      fullName: r.fullName,
      stars: r.stars,
      score: r.score,
      description: r.description.slice(0, 200),
      topics: r.topics,
      htmlUrl: r.htmlUrl,
      hasSkillFile: r.hasSkillFile,
      license: r.license,
    })),
    total: filtered.length,
    errors: errors.length > 0 ? errors : undefined,
  };
}

async function handleScan(args: z.infer<typeof GitHubSkillsScanSchema>) {
  const findings = scanText(args.content, args.repoName);
  return {
    repoName: args.repoName,
    clean: findings.length === 0,
    findings: findings.map((f) => ({
      pattern: f.pattern,
      context: f.context,
    })),
  };
}

async function handleInstall(args: z.infer<typeof GitHubSkillsInstallSchema>) {
  const results: SkillInstallResult[] = [];
  const skillName = args.repoName.split("/").pop() || args.repoName;

  for (const target of args.targets) {
    try {
      const dest = resolveInstallPath(target, skillName, args.description);
      // In a real implementation, this would clone the repo and copy files.
      // For now, we return the planned install path as a dry-run result — matches
      // the honest `action: "planned"` the REST route (/api/github-skills POST)
      // reports for the same operation.
      results.push({
        target,
        ok: true,
        action: "planned",
        destDir: dest,
      });
    } catch (err) {
      results.push({
        target,
        ok: false,
        action: "error",
        error: sanitizeErrorMessage((err as Error).message),
      });
    }
  }

  return {
    repoName: args.repoName,
    skillName,
    results,
    allOk: results.every((r) => r.ok),
  };
}

// ── Tool Definitions ─────────────────────────────────────────────────────────

export const githubSkillTools = {
  omniroute_github_skills_search: {
    name: "omniroute_github_skills_search",
    description:
      "Search GitHub for agent skill repositories that contain SKILL.md, CLAUDE.md, .cursorrules, or similar agent configuration files. " +
      "Returns scored results sorted by relevance. Scores are 0.0–1.0 based on stars, name signals, description keywords, and topic tags. " +
      "Ideal for discovering community agent skills from GitHub.",
    inputSchema: GitHubSkillsSearchSchema,
    scopes: ["read:skills"],
    handler: handleSearch,
  },

  omniroute_github_skills_scan: {
    name: "omniroute_github_skills_scan",
    description:
      "Scan SKILL.md or README content from a GitHub repo for blocked patterns including eval(base64), " +
      "hardcoded secrets (API keys, passwords, private keys), dangerous function calls (os.system, subprocess.Popen), " +
      "and other malware indicators. Returns findings with context or 'clean' status.",
    inputSchema: GitHubSkillsScanSchema,
    scopes: ["read:skills"],
    handler: handleScan,
  },

  omniroute_github_skills_install: {
    name: "omniroute_github_skills_install",
    description:
      "Preview or plan the installation of a discovered GitHub skill into one or more agent directories " +
      "(Hermes: ~/AppData/Local/hermes/skills/, Claude: ~/.claude/skills/, Gemini: ~/.gemini/skills/, " +
      "OpenCode: ~/.opencode/skills/). Categorizes the skill based on its name and description. " +
      "Returns the target paths where the skill would be installed.",
    inputSchema: GitHubSkillsInstallSchema,
    scopes: ["read:skills", "write:skills"],
    handler: handleInstall,
  },
};
