#!/usr/bin/env python3
"""
Supreme 2 MAX Install Manifest Manager
Tracks tools installed by Supreme 2 MAX to prevent accidental uninstallation of user tools
"""

import json
import os
from datetime import datetime
from pathlib import Path
from typing import Dict, Optional, List


class InstallManifest:
    """Manages the Supreme 2 MAX install manifest"""

    def __init__(self, manifest_path: Optional[Path] = None):
        """Initialize manifest manager

        Args:
            manifest_path: Path to manifest file (defaults to ~/.supreme2l/installed_tools.json)
        """
        if manifest_path is None:
            # Use ~/.supreme2l/installed_tools.json by default
            home = Path.home()
            supreme2l_dir = home / '.supreme2l'
            supreme2l_dir.mkdir(parents=True, exist_ok=True)
            self.manifest_path = supreme2l_dir / 'installed_tools.json'
        else:
            self.manifest_path = manifest_path

        self.data = self._load()

    def _load(self) -> Dict:
        """Load manifest from disk"""
        default_data = {'tools': {}, 'version': '1.0'}

        if not self.manifest_path.exists():
            return default_data

        try:
            with open(self.manifest_path, 'r') as f:
                data = json.load(f)
                # Ensure 'tools' key exists (handle old/malformed manifests)
                if 'tools' not in data:
                    data['tools'] = {}
                return data
        except (json.JSONDecodeError, IOError):
            # Corrupted manifest, start fresh
            return default_data

    def _save(self):
        """Save manifest to disk"""
        self.manifest_path.parent.mkdir(parents=True, exist_ok=True)
        with open(self.manifest_path, 'w') as f:
            json.dump(self.data, f, indent=2)

    def mark_installed(self, tool_name: str, package_manager: str,
                      package_id: Optional[str] = None, version: Optional[str] = None,
                      already_existed: bool = False):
        """Mark a tool as installed

        Args:
            tool_name: Name of the tool (e.g., 'shellcheck')
            package_manager: Package manager used (e.g., 'winget', 'pip', 'npm')
            package_id: Package ID/name in the package manager
            version: Version installed
            already_existed: True if tool was already installed (Supreme 2 MAX didn't install it)
        """
        self.data['tools'][tool_name] = {
            'installed_by_medusa': not already_existed,
            'installed_at': datetime.utcnow().isoformat(),
            'package_manager': package_manager,
            'package_id': package_id or tool_name,
            'version': version,
        }

        if already_existed:
            self.data['tools'][tool_name]['note'] = 'Pre-existing installation'

        self._save()

    def mark_uninstalled(self, tool_name: str):
        """Remove a tool from the manifest

        Args:
            tool_name: Name of the tool
        """
        if tool_name in self.data['tools']:
            del self.data['tools'][tool_name]
            self._save()

    def was_installed_by_supreme2l(self, tool_name: str) -> bool:
        """Check if a tool was installed by Supreme 2 MAX

        Args:
            tool_name: Name of the tool

        Returns:
            True if Supreme 2 MAX installed it, False otherwise
        """
        tool_info = self.data['tools'].get(tool_name, {})
        return tool_info.get('installed_by_medusa', False)

    def get_supreme2l_installed_tools(self) -> List[str]:
        """Get list of tools installed by Supreme 2 MAX

        Returns:
            List of tool names
        """
        return [
            name for name, info in self.data['tools'].items()
            if info.get('installed_by_medusa', False)
        ]

    def get_all_tracked_tools(self) -> List[str]:
        """Get list of all tracked tools (including pre-existing)

        Returns:
            List of tool names
        """
        return list(self.data['tools'].keys())

    def get_tool_info(self, tool_name: str) -> Optional[Dict]:
        """Get installation info for a tool

        Args:
            tool_name: Name of the tool

        Returns:
            Tool info dict or None if not found
        """
        return self.data['tools'].get(tool_name)

    def is_support_software(self, tool_name: str) -> bool:
        """Check if a tool is support software (runtime/compiler)

        Args:
            tool_name: Name of the tool

        Returns:
            True if it's support software that should not be uninstalled
        """
        # List of support software that should never be auto-uninstalled
        support_tools = {
            'python', 'python3', 'pip', 'pip3',
            'ruby', 'gem',
            'node', 'npm', 'npx',
            'go', 'cargo', 'rustc', 'rustup',
            'java', 'javac', 'maven', 'gradle',
            'dotnet', 'csc',
            'php', 'composer',
            'perl', 'cpan',
            'elixir', 'mix',
            'dart', 'pub',
            'swift', 'swiftc',
            'r', 'Rscript',
        }
        return tool_name.lower() in support_tools


# Global manifest instance
_manifest = None


def get_manifest() -> InstallManifest:
    """Get the global install manifest instance"""
    global _manifest
    if _manifest is None:
        _manifest = InstallManifest()
    return _manifest
