from typing import Dict, Any, Tuple, Callable, Optional
from app.core.tools.base import BaseToolPlugin
import logging

logger = logging.getLogger(__name__)


class ReadSkillArtifactTool(BaseToolPlugin):
    """
    Lazy-loading tool that allows the AI agent to read any file stored in
    the Skill Virtual File System (VFS) on demand.

    Instead of injecting the entire skill system_prompt or 1000-line scripts
    into the initial context window, the agent is given only a brief summary
    and can call this tool to read the relevant SKILL.md or any script in
    the /scripts/ or /artifacts/ directories when it needs them.
    """

    @property
    def name(self) -> str:
        return "read_skill_artifact"

    @property
    def retries(self) -> int:
        return 0  # No retries needed — it's a simple DB read

    def prepare_task(self, args: Dict[str, Any], context: Dict[str, Any]) -> Tuple[Optional[Callable], Dict[str, Any]]:
        skill_name = args.get("skill_name", "").strip()
        file_path = args.get("file_path", "SKILL.md").strip()
        db = context.get("db")

        if not skill_name:
            return None, {"success": False, "error": "skill_name is required"}
        if not db:
            return None, {"success": False, "error": "Database context not available"}

        def _read_artifact(skill_name: str, file_path: str) -> dict:
            # 1. Try resolving skill from FS first (VFS format)
            try:
                from app.core.skills.fs_loader import fs_loader
                all_fs_skills = fs_loader.get_all_skills()
                for fs_skill in all_fs_skills:
                    if fs_skill.get("name") == skill_name:
                        for f in fs_skill.get("files", []):
                            if f.get("file_path") == file_path:
                                content_str = str(f.get("content", ""))
                                logger.info(f"[ReadSkillArtifact] Lazy-loaded '{file_path}' from FS skill '{skill_name}' ({len(content_str)} chars)")
                                return {
                                    "success": True,
                                    "skill_name": skill_name,
                                    "file_path": file_path,
                                    "content": content_str
                                }
                        return {"success": False, "error": f"File '{file_path}' not found in virtual skill '{skill_name}'.", "hint": "Check the available skill files."}
            except Exception as e:
                logger.warning(f"Error checking FS skills for artifact: {e}")

            # 2. Fallback to DB definition
            from app.db import models as m

            skill = db.query(m.Skill).filter(m.Skill.name == skill_name).first()
            if not skill:
                return {"success": False, "error": f"Skill '{skill_name}' not found."}

            skill_file = (
                db.query(m.SkillFile)
                .filter(m.SkillFile.skill_id == skill.id, m.SkillFile.file_path == file_path)
                .first()
            )
            if not skill_file:
                return {
                    "success": False,
                    "error": f"File '{file_path}' not found in skill '{skill_name}'.",
                    "hint": "Use list_skill_files to discover available files."
                }

            logger.info(f"[ReadSkillArtifact] Lazy-loaded '{file_path}' from skill '{skill_name}' ({len(skill_file.content or '')} chars)")
            return {
                "success": True,
                "skill_name": skill_name,
                "file_path": file_path,
                "content": skill_file.content or ""
            }

        return _read_artifact, {"skill_name": skill_name, "file_path": file_path}
