"""Boost Engine — main orchestrator for cross-platform performance optimization."""
from __future__ import annotations

import json
import logging
import time
from datetime import datetime, timezone
from pathlib import Path
from typing import Optional

from mesh_boost.optimizer.base import IS_WINDOWS, IS_LINUX, is_admin

logger = logging.getLogger(__name__)

_STATE_FILE = Path.home() / ".mesh-optimizer" / "boost_state" / "engine.json"


class BoostEngine:
    """Orchestrate all optimization modules based on license tier and platform."""

    def __init__(self, tier: str = "gamer"):
        """
        Args:
            tier: License tier — "gamer" ($5), "pro" ($10), "community" (free, no boost)
        """
        self.tier = tier
        self._active = False
        self._results: list[dict] = []
        self._start_time: Optional[float] = None

    def start(self, dry_run: bool = False) -> dict:
        """Apply all optimizations for the current tier.

        Returns a summary dict with applied/skipped/failed counts.
        """
        if not IS_WINDOWS and not IS_LINUX:
            return {"error": "Boost requires Windows or Linux"}

        if self.tier == "community":
            return {"error": "Boost requires Gamer ($5/mo) or Pro ($10/mo) tier"}

        if self._active:
            return {"status": "already_active", "results": self._results}

        logger.info("Boost starting (tier=%s, platform=%s, dry_run=%s)",
                     self.tier, "windows" if IS_WINDOWS else "linux", dry_run)
        self._results = []
        self._start_time = time.time()

        if IS_WINDOWS:
            self._start_windows(dry_run)
        elif IS_LINUX:
            self._start_linux(dry_run)

        self._active = True
        self._save_state()

        summary = self._summarize()
        logger.info("Boost active: %s", summary)
        return summary

    def _start_windows(self, dry_run: bool):
        """Apply Windows-specific optimizations."""
        # Gamer tier: power + network
        from mesh_boost.optimizer.power import PowerOptimizer
        r = PowerOptimizer().apply(dry_run=dry_run)
        self._results.append(r.to_dict())

        from mesh_boost.optimizer.network import NetworkOptimizer
        r = NetworkOptimizer().apply(dry_run=dry_run)
        self._results.append(r.to_dict())

        # Both tiers: process optimizations
        from mesh_boost.optimizer.process import ProcessOptimizer
        r = ProcessOptimizer().apply(dry_run=dry_run)
        self._results.append(r.to_dict())

        # Pro tier: GPU
        if self.tier == "pro":
            from mesh_boost.optimizer.gpu import GPUOptimizer
            r = GPUOptimizer().apply(dry_run=dry_run)
            self._results.append(r.to_dict())

    def _start_linux(self, dry_run: bool):
        """Apply Linux-specific optimizations."""
        # Gamer tier: power + network
        from mesh_boost.optimizer.linux_power import LinuxPowerOptimizer
        r = LinuxPowerOptimizer().apply(dry_run=dry_run)
        self._results.append(r.to_dict())

        from mesh_boost.optimizer.linux_network import LinuxNetworkOptimizer
        r = LinuxNetworkOptimizer().apply(dry_run=dry_run)
        self._results.append(r.to_dict())

        # Both tiers: process optimizations
        from mesh_boost.optimizer.linux_process import LinuxProcessOptimizer
        r = LinuxProcessOptimizer().apply(dry_run=dry_run)
        self._results.append(r.to_dict())

        # Pro tier: GPU
        if self.tier == "pro":
            from mesh_boost.optimizer.linux_gpu import LinuxGPUOptimizer
            r = LinuxGPUOptimizer().apply(dry_run=dry_run)
            self._results.append(r.to_dict())

    def stop(self) -> dict:
        """Restore all original settings."""
        if not self._active:
            return {"status": "not_active"}

        logger.info("Boost stopping — restoring original settings")
        restore_results = []

        if IS_WINDOWS:
            self._stop_windows(restore_results)
        elif IS_LINUX:
            self._stop_linux(restore_results)

        self._active = False
        self._start_time = None
        self._clear_state()

        return {"status": "restored", "results": restore_results}

    def _stop_windows(self, results: list):
        from mesh_boost.optimizer.power import PowerOptimizer
        results.append(PowerOptimizer().restore().to_dict())

        from mesh_boost.optimizer.network import NetworkOptimizer
        results.append(NetworkOptimizer().restore().to_dict())

        from mesh_boost.optimizer.process import ProcessOptimizer
        results.append(ProcessOptimizer().restore().to_dict())

        from mesh_boost.optimizer.gpu import GPUOptimizer
        results.append(GPUOptimizer().restore().to_dict())

    def _stop_linux(self, results: list):
        from mesh_boost.optimizer.linux_power import LinuxPowerOptimizer
        results.append(LinuxPowerOptimizer().restore().to_dict())

        from mesh_boost.optimizer.linux_network import LinuxNetworkOptimizer
        results.append(LinuxNetworkOptimizer().restore().to_dict())

        from mesh_boost.optimizer.linux_process import LinuxProcessOptimizer
        results.append(LinuxProcessOptimizer().restore().to_dict())

        from mesh_boost.optimizer.linux_gpu import LinuxGPUOptimizer
        results.append(LinuxGPUOptimizer().restore().to_dict())

    def status(self) -> dict:
        """Get current boost status."""
        info = {
            "active": self._active,
            "tier": self.tier,
            "is_admin": is_admin(),
            "platform": "windows" if IS_WINDOWS else "linux" if IS_LINUX else "unsupported",
        }

        if self._active and self._start_time:
            info["uptime_s"] = round(time.time() - self._start_time, 1)
            info["results"] = self._results

        # Get live status from platform-specific modules
        if IS_WINDOWS:
            self._status_windows(info)
        elif IS_LINUX:
            self._status_linux(info)

        return info

    def _status_windows(self, info: dict):
        try:
            from mesh_boost.optimizer.power import PowerOptimizer
            info["power"] = PowerOptimizer().get_status()
        except Exception:
            pass
        try:
            from mesh_boost.optimizer.network import NetworkOptimizer
            info["network"] = NetworkOptimizer().get_status()
        except Exception:
            pass
        try:
            from mesh_boost.optimizer.process import ProcessOptimizer
            info["process"] = ProcessOptimizer().get_status()
        except Exception:
            pass
        try:
            from mesh_boost.optimizer.gpu import GPUOptimizer
            info["gpu"] = GPUOptimizer().get_status()
        except Exception:
            pass

    def _status_linux(self, info: dict):
        try:
            from mesh_boost.optimizer.linux_power import LinuxPowerOptimizer
            info["power"] = LinuxPowerOptimizer().get_status()
        except Exception:
            pass
        try:
            from mesh_boost.optimizer.linux_network import LinuxNetworkOptimizer
            info["network"] = LinuxNetworkOptimizer().get_status()
        except Exception:
            pass
        try:
            from mesh_boost.optimizer.linux_process import LinuxProcessOptimizer
            info["process"] = LinuxProcessOptimizer().get_status()
        except Exception:
            pass
        try:
            from mesh_boost.optimizer.linux_gpu import LinuxGPUOptimizer
            info["gpu"] = LinuxGPUOptimizer().get_status()
        except Exception:
            pass

    def _summarize(self) -> dict:
        total_applied = sum(len(r.get("applied", [])) for r in self._results)
        total_skipped = sum(len(r.get("skipped", [])) for r in self._results)
        total_failed = sum(len(r.get("failed", [])) for r in self._results)
        return {
            "status": "active",
            "tier": self.tier,
            "applied": total_applied,
            "skipped": total_skipped,
            "failed": total_failed,
            "results": self._results,
        }

    def _save_state(self):
        _STATE_FILE.parent.mkdir(parents=True, exist_ok=True)
        state = {
            "active": True,
            "tier": self.tier,
            "started_at": datetime.now(timezone.utc).isoformat(),
        }
        _STATE_FILE.write_text(json.dumps(state, indent=2))

    def _clear_state(self):
        if _STATE_FILE.exists():
            _STATE_FILE.unlink()

    @classmethod
    def is_boost_active(cls) -> bool:
        """Check if boost was previously started (survives process restarts)."""
        if _STATE_FILE.exists():
            try:
                state = json.loads(_STATE_FILE.read_text())
                return state.get("active", False)
            except Exception:
                pass
        return False
