import os
import json
import logging
from typing import List, Dict, Any
import jsonschema
from jsonschema import validate
from jsonschema.exceptions import ValidationError

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

class SkillCataloger:
    """
    A class to catalog skills from a directory, extract information, validate schemas,
    and generate documentation.
    """

    def __init__(self, skills_directory: str):
        """
        Initializes the SkillCataloger.

        Args:
            skills_directory (str): The directory containing the skill files.
        """
        self.skills_directory = skills_directory
        self.catalog: List[Dict[str, Any]] = []

    def load_skill(self, skill_file_path: str) -> Dict[str, Any]:
        """
        Loads a skill from a JSON file.

        Args:
            skill_file_path (str): The path to the skill file.

        Returns:
            Dict[str, Any]: The loaded skill data as a dictionary.  Returns an empty dictionary if loading fails.
        """
        try:
            with open(skill_file_path, 'r') as f:
                skill_data = json.load(f)
            return skill_data
        except FileNotFoundError:
            logging.error(f"Skill file not found: {skill_file_path}")
            return {}
        except json.JSONDecodeError as e:
            logging.error(f"Error decoding JSON in {skill_file_path}: {e}")
            return {}
        except Exception as e:
            logging.error(f"An unexpected error occurred while loading {skill_file_path}: {e}")
            return {}

    def extract_skill_info(self, skill_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        Extracts relevant information from the skill data.

        Args:
            skill_data (Dict[str, Any]): The skill data dictionary.

        Returns:
            Dict[str, Any]: A dictionary containing the extracted skill information.
        """
        try:
            skill_name = skill_data.get("skill_name", "Unnamed Skill")
            description = skill_data.get("description", "No description provided.")
            parameters = skill_data.get("parameters", [])
            examples = skill_data.get("examples", [])

            return {
                "skill_name": skill_name,
                "description": description,
                "parameters": parameters,
                "examples": examples
            }
        except Exception as e:
            logging.error(f"Error extracting skill info: {e}")
            return {}

    def validate_skill_schema(self, skill_data: Dict[str, Any], schema: Dict[str, Any]) -> bool:
        """
        Validates the skill data against a given JSON schema.

        Args:
            skill_data (Dict[str, Any]): The skill data to validate.
            schema (Dict[str, Any]): The JSON schema to validate against.

        Returns:
            bool: True if the skill data is valid, False otherwise.
        """
        try:
            validate(instance=skill_data, schema=schema)
            return True
        except ValidationError as e:
            logging.error(f"Schema validation error: {e}")
            return False
        except Exception as e:
            logging.error(f"An unexpected error occurred during schema validation: {e}")
            return False

    def build_catalog(self, schema_path: str) -> None:
        """
        Builds the skill catalog by iterating through the skills directory,
        extracting information, and validating schemas.

        Args:
            schema_path (str): The path to the JSON schema file.
        """
        try:
            with open(schema_path, 'r') as f:
                schema = json.load(f)
        except FileNotFoundError:
            logging.error(f"Schema file not found: {schema_path}")
            return
        except json.JSONDecodeError as e:
            logging.error(f"Error decoding JSON in schema file {schema_path}: {e}")
            return
        except Exception as e:
            logging.error(f"An unexpected error occurred while loading schema from {schema_path}: {e}")
            return

        for filename in os.listdir(self.skills_directory):
            if filename.endswith(".json"):
                skill_file_path = os.path.join(self.skills_directory, filename)
                skill_data = self.load_skill(skill_file_path)

                if not skill_data:
                    continue  # Skip to the next file if loading failed.

                if not self.validate_skill_schema(skill_data, schema):
                    logging.warning(f"Skill {filename} failed schema validation. Skipping.")
                    continue

                skill_info = self.extract_skill_info(skill_data)
                self.catalog.append(skill_info)
                logging.info(f"Skill {filename} cataloged successfully.")

    def generate_documentation(self, output_file: str) -> None:
        """
        Generates skill documentation from the catalog and saves it to a file.

        Args:
            output_file (str): The path to the output documentation file.
        """
        try:
            with open(output_file, 'w') as f:
                for skill in self.catalog:
                    f.write(f"## {skill['skill_name']}\n")
                    f.write(f"{skill['description']}\n\n")
                    f.write("### Parameters:\n")
                    if skill['parameters']:
                        for param in skill['parameters']:
                            f.write(f"- {param.get('name', 'Unnamed')}: {param.get('description', 'No description')}\n")
                    else:
                        f.write("No parameters.\n")
                    f.write("\n")
                    f.write("### Examples:\n")
                    if skill['examples']:
                        for example in skill['examples']:
                            f.write(f"- {example}\n")
                    else:
                        f.write("No examples.\n")
                    f.write("\n---\n\n")
            logging.info(f"Skill documentation generated successfully at {output_file}")
        except Exception as e:
            logging.error(f"Error generating documentation: {e}")

def main():
    """
    Main function to demonstrate the usage of the SkillCataloger.
    """
    skills_directory = "/mnt/e/genesis-system/skills"  # Replace with your skills directory
    schema_path = "/mnt/e/genesis-system/core/knowledge/skill_schema.json"  # Replace with your schema path
    output_file = "/mnt/e/genesis-system/skill_documentation.md"  # Replace with your desired output file

    # Create dummy skills directory and files if they don't exist for testing
    if not os.path.exists(skills_directory):
        os.makedirs(skills_directory)
        # Create a dummy skill file
        with open(os.path.join(skills_directory, "dummy_skill.json"), "w") as f:
            json.dump({
                "skill_name": "Dummy Skill",
                "description": "A dummy skill for testing.",
                "parameters": [{"name": "input", "description": "Some input"}],
                "examples": ["Dummy example"]
            }, f)

    # Create a dummy schema file
    if not os.path.exists(schema_path):
        with open(schema_path, "w") as f:
            json.dump({
                "type": "object",
                "properties": {
                    "skill_name": {"type": "string"},
                    "description": {"type": "string"},
                    "parameters": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "name": {"type": "string"},
                                "description": {"type": "string"}
                            },
                            "required": ["name", "description"]
                        }
                    },
                    "examples": {"type": "array", "items": {"type": "string"}}
                },
                "required": ["skill_name", "description", "parameters", "examples"]
            }, f)

    cataloger = SkillCataloger(skills_directory)
    cataloger.build_catalog(schema_path)
    cataloger.generate_documentation(output_file)

if __name__ == "__main__":
    main()
