from __future__ import annotations

import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch

from memnixa.skills import build_skills_prompt, discover_skills
from memnixa.tools.skills import ListSkillsTool, ReadSkillTool


class SkillsTests(unittest.TestCase):
    def test_discover_skills_prefers_workspace_over_managed(self) -> None:
        with tempfile.TemporaryDirectory() as temp_dir:
            workspace = Path(temp_dir) / "workspace"
            workspace.mkdir(parents=True, exist_ok=True)
            managed_home = Path(temp_dir) / ".memnixa"
            managed_root = managed_home / "skills" / "demo-skill"
            managed_root.mkdir(parents=True, exist_ok=True)
            (managed_root / "SKILL.md").write_text(
                "---\nname: demo-skill\ndescription: managed skill\n---\n",
                encoding="utf-8",
            )
            workspace_root = workspace / "skills" / "demo-skill"
            workspace_root.mkdir(parents=True, exist_ok=True)
            (workspace_root / "SKILL.md").write_text(
                "---\nname: demo-skill\ndescription: workspace skill\n---\n",
                encoding="utf-8",
            )

            with patch("memnixa.skills.get_memnixa_home", return_value=managed_home):
                with patch("pathlib.Path.home", return_value=Path(temp_dir) / "home"):
                    skills = discover_skills(workspace)

        self.assertEqual(len(skills), 1)
        self.assertEqual(skills[0].description, "workspace skill")
        self.assertEqual(skills[0].source, "workspace")

    def test_build_skills_prompt_lists_available_skills(self) -> None:
        with tempfile.TemporaryDirectory() as temp_dir:
            workspace = Path(temp_dir)
            skill_dir = workspace / "skills" / "demo-skill"
            skill_dir.mkdir(parents=True, exist_ok=True)
            (skill_dir / "SKILL.md").write_text(
                "---\nname: demo-skill\ndescription: demo description\n---\n",
                encoding="utf-8",
            )
            with patch("memnixa.skills.get_memnixa_home", return_value=Path(temp_dir) / ".memnixa"):
                with patch("pathlib.Path.home", return_value=Path(temp_dir) / "home"):
                    skills = discover_skills(workspace)

        prompt = build_skills_prompt(skills)
        self.assertIsNotNone(prompt)
        self.assertIn("<available_skills>", prompt)
        self.assertIn("<skill_id>demo-skill</skill_id>", prompt)
        self.assertIn("<description>demo description</description>", prompt)

    def test_skill_tools_can_list_and_read_skill_files(self) -> None:
        with tempfile.TemporaryDirectory() as temp_dir:
            workspace = Path(temp_dir)
            skill_dir = workspace / "skills" / "demo-skill"
            refs_dir = skill_dir / "references"
            refs_dir.mkdir(parents=True, exist_ok=True)
            (skill_dir / "SKILL.md").write_text(
                "---\nname: demo-skill\ndescription: demo description\n---\n\n# Demo Skill\n",
                encoding="utf-8",
            )
            (refs_dir / "guide.md").write_text(
                "Use this reference when needed.",
                encoding="utf-8",
            )
            with patch("memnixa.skills.get_memnixa_home", return_value=Path(temp_dir) / ".memnixa"):
                with patch("pathlib.Path.home", return_value=Path(temp_dir) / "home"):
                    skills = discover_skills(workspace)

            list_result = ListSkillsTool(skills).execute({})
            read_main_result = ReadSkillTool(skills).execute({"skill_id": "demo-skill"})
            read_ref_result = ReadSkillTool(skills).execute(
                {"skill_id": "demo-skill", "path": "references/guide.md"}
            )

        self.assertTrue(list_result.ok)
        self.assertEqual(list_result.data["skills"][0]["skill_id"], "demo-skill")
        self.assertTrue(read_main_result.ok)
        self.assertIn("# Demo Skill", read_main_result.data["content"])
        self.assertTrue(read_ref_result.ok)
        self.assertEqual(read_ref_result.data["path"], "references/guide.md")
        self.assertIn("Use this reference", read_ref_result.data["content"])


if __name__ == "__main__":
    unittest.main()
