import hashlib
import hmac
import os
from pathlib import Path
from typing import Optional
import json


class PluginSecurity:
    """Plugin security manager"""
    
    def __init__(self, plugins_dir: str = None):
        self.plugins_dir = Path(plugins_dir or os.path.expanduser('~/.feather/plugins'))
        self.signatures_file = self.plugins_dir / 'signatures.json'
        self.signatures = self._load_signatures()
    
    def _load_signatures(self) -> dict:
        """Load plugin signatures"""
        if not self.signatures_file.exists():
            return {}
        
        with open(self.signatures_file, 'r') as f:
            return json.load(f)
    
    def _save_signatures(self):
        """Save plugin signatures"""
        self.signatures_file.parent.mkdir(parents=True, exist_ok=True)
        with open(self.signatures_file, 'w') as f:
            json.dump(self.signatures, f, indent=2)
    
    def sign_plugin(self, plugin_path: Path, secret_key: str) -> str:
        """Sign a plugin with HMAC"""
        plugin_content = self._get_plugin_content(plugin_path)
        signature = hmac.new(
            secret_key.encode(),
            plugin_content.encode(),
            hashlib.sha256
        ).hexdigest()
        
        plugin_name = plugin_path.name
        self.signatures[plugin_name] = signature
        self._save_signatures()
        
        return signature
    
    def verify_plugin(self, plugin_path: Path, secret_key: str) -> bool:
        """Verify a plugin signature"""
        plugin_name = plugin_path.name
        
        if plugin_name not in self.signatures:
            return False
        
        expected_signature = self.signatures[plugin_name]
        plugin_content = self._get_plugin_content(plugin_path)
        
        actual_signature = hmac.new(
            secret_key.encode(),
            plugin_content.encode(),
            hashlib.sha256
        ).hexdigest()
        
        return hmac.compare_digest(expected_signature, actual_signature)
    
    def _get_plugin_content(self, plugin_path: Path) -> str:
        """Get plugin content hash"""
        content_parts = []
        
        for py_file in sorted(plugin_path.rglob('*.py')):
            with open(py_file, 'r') as f:
                content_parts.append(f.read())
        
        return ''.join(content_parts)
    
    def check_permissions(self, plugin_name: str, permission: str) -> bool:
        """Check if plugin has permission"""
        permissions_file = self.plugins_dir / plugin_name / 'permissions.json'
        
        if not permissions_file.exists():
            return False
        
        with open(permissions_file, 'r') as f:
            permissions = json.load(f)
        
        return permission in permissions.get('allowed', [])


class Sandbox:
    """Plugin sandbox environment"""
    
    def __init__(self, allowed_modules: list = None):
        self.allowed_modules = allowed_modules or [
            'feather',
            'datetime',
            'json',
            'typing'
        ]
    
    def execute(self, code: str, globals_dict: dict = None):
        """Execute code in sandbox"""
        if globals_dict is None:
            globals_dict = {'__builtins__': {}}
        
        for module_name in self.allowed_modules:
            if module_name not in globals_dict:
                globals_dict[module_name] = __import__(module_name)
        
        exec(code, globals_dict)
        return globals_dict
