from __future__ import annotations

import json
from pathlib import Path
from typing import Any, Dict, List


class ServiceRemediation:
    """Model and reversible control for Windows services."""

    def __init__(self, services_path: str | Path):
        self.services_path = Path(services_path)
        self.services_path.parent.mkdir(parents=True, exist_ok=True)
        if not self.services_path.exists():
            self.services_path.write_text("[]", encoding="utf-8")
        self._backup_store = self.services_path.parent / "services_backup.json"

    def load_services(self) -> Dict[str, Dict[str, Any]]:
        try:
            payload = json.loads(self.services_path.read_text(encoding="utf-8"))
        except (json.JSONDecodeError, OSError):
            payload = []
        services = {}
        for item in payload:
            name = str(item.get("name") or "unknown")
            services[name] = item
        return services

    def capture_snapshot(self) -> Dict[str, Any]:
        current = self.load_services()
        self._backup_store.write_text(json.dumps(current, indent=2, sort_keys=True), encoding="utf-8")
        return {"before_state": current, "backup_path": str(self._backup_store)}

    def disable_service(self, name: str) -> Dict[str, Any]:
        services = self.load_services()
        if name not in services:
            return {"name": name, "status": "missing"}

        self.capture_snapshot()
        current = services[name]
        current["enabled"] = False
        current["status"] = "disabled"
        self._write_services(list(services.values()))
        return {"name": name, "status": "disabled", "before": current}

    def restore_service(self, name: str) -> Dict[str, Any]:
        if self._backup_store.exists():
            backup = json.loads(self._backup_store.read_text(encoding="utf-8"))
            if isinstance(backup, dict) and name in backup:
                services = self.load_services()
                services[name] = backup[name]
                self._write_services(list(services.values()))
                return {"name": name, "status": "restored", "after": backup[name]}

        services = self.load_services()
        if name not in services:
            return {"name": name, "status": "missing"}
        services[name]["enabled"] = True
        services[name]["status"] = "running"
        self._write_services(list(services.values()))
        return {"name": name, "status": "restored", "after": services[name]}

    def _write_services(self, services: List[Dict[str, Any]]) -> None:
        self.services_path.write_text(json.dumps(services, indent=2, sort_keys=True), encoding="utf-8")
