"""
State management for Context Custodians
"""

import json
import hashlib
from pathlib import Path
from typing import Dict, Any
from datetime import datetime


class StateManager:
    """Manages persistent state for the Memory Warden system"""

    def __init__(self, config_dir: Path):
        self.config_dir = config_dir
        self.state_file = config_dir / 'state.json'
        self._state = self._load_state()

    def _load_state(self) -> Dict[str, Any]:
        """Load state from JSON file"""
        if self.state_file.exists():
            try:
                with open(self.state_file, 'r') as f:
                    return json.load(f)
            except json.JSONDecodeError:
                pass

        # Return default state
        return {
            'version': '0.1.0',
            'created_at': datetime.now().isoformat(),
            'file_hashes': {},
            'last_scan': None,
            'agent_status': {},
            'system_health': 'healthy'
        }

    def save_state(self):
        """Save current state to file"""
        self._state['last_updated'] = datetime.now().isoformat()
        with open(self.state_file, 'w') as f:
            json.dump(self._state, f, indent=2, default=str)

    def get_file_hash(self, file_path: str) -> str:
        """Get stored hash for a file"""
        return self._state.get('file_hashes', {}).get(file_path)

    def set_file_hash(self, file_path: str, hash_value: str):
        """Set hash for a file"""
        if 'file_hashes' not in self._state:
            self._state['file_hashes'] = {}
        self._state['file_hashes'][file_path] = hash_value
        self.save_state()

    def calculate_file_hash(self, file_path: Path) -> str:
        """Calculate SHA256 hash of a file"""
        if not file_path.exists():
            return None

        try:
            with open(file_path, 'rb') as f:
                return hashlib.sha256(f.read()).hexdigest()
        except (OSError, IOError):
            return None

    def update_file_hashes(self, files: Dict[str, Path]):
        """Update hashes for multiple files"""
        for file_path_str, file_path in files.items():
            current_hash = self.calculate_file_hash(file_path)
            if current_hash:
                self.set_file_hash(file_path_str, current_hash)

    def get_changed_files(self, files: Dict[str, Path]) -> Dict[str, Path]:
        """Get files that have changed since last scan"""
        changed = {}
        for file_path_str, file_path in files.items():
            stored_hash = self.get_file_hash(file_path_str)
            current_hash = self.calculate_file_hash(file_path)
            if stored_hash != current_hash and current_hash is not None:
                changed[file_path_str] = file_path
        return changed

    def set_agent_status(self, agent_name: str, status: str, details: Dict = None):
        """Set status for an agent"""
        if 'agent_status' not in self._state:
            self._state['agent_status'] = {}

        self._state['agent_status'][agent_name] = {
            'status': status,
            'timestamp': datetime.now().isoformat(),
            'details': details or {}
        }
        self.save_state()

    def get_agent_status(self, agent_name: str) -> Dict:
        """Get status for an agent"""
        return self._state.get('agent_status', {}).get(agent_name, {})

    def set_system_health(self, health: str):
        """Set overall system health"""
        self._state['system_health'] = health
        self.save_state()

    def get_system_health(self) -> str:
        """Get overall system health"""
        return self._state.get('system_health', 'unknown')

    def set_last_scan(self, timestamp: str = None):
        """Set timestamp of last scan"""
        self._state['last_scan'] = timestamp or datetime.now().isoformat()
        self.save_state()

    def get_last_scan(self) -> str:
        """Get timestamp of last scan"""
        return self._state.get('last_scan')