from __future__ import annotations

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


class DefenderRemediation:
    """Model Windows Defender posture and restore previous values in a reversible way.

    This project intentionally does not disable the operating system's security stack.
    Instead, this module tracks the expected Defender posture and can restore a known-good
    state after a suspicious change or a planned clean-up operation.
    """

    def __init__(self, defender_state_path: str | Path):
        self.defender_state_path = Path(defender_state_path)
        self.defender_state_path.parent.mkdir(parents=True, exist_ok=True)
        if not self.defender_state_path.exists():
            self.defender_state_path.write_text(json.dumps({"settings": {}}, indent=2, sort_keys=True), encoding="utf-8")
        self._backup_store = self.defender_state_path.parent / "defender_state_backup.json"

    def load_state(self) -> Dict[str, Any]:
        try:
            payload = json.loads(self.defender_state_path.read_text(encoding="utf-8"))
        except (json.JSONDecodeError, OSError):
            payload = {"settings": {}}
        if not isinstance(payload, dict):
            payload = {"settings": {}}
        if "settings" not in payload or not isinstance(payload["settings"], dict):
            payload["settings"] = {}
        return payload

    def capture_snapshot(self) -> Dict[str, Any]:
        current = self.load_state()
        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 set_setting(self, setting_name: str, value: Any) -> Dict[str, Any]:
        state = self.load_state()
        if "settings" not in state or not isinstance(state["settings"], dict):
            state["settings"] = {}
        self.capture_snapshot()
        state["settings"][setting_name] = value
        self._write_state(state)
        return {"name": setting_name, "status": "updated", "value": value}

    def restore_setting(self, setting_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 "settings" in backup and isinstance(backup["settings"], dict) and setting_name in backup["settings"]:
                state = self.load_state()
                state["settings"][setting_name] = backup["settings"][setting_name]
                self._write_state(state)
                return {"name": setting_name, "status": "restored", "value": backup["settings"][setting_name]}

        state = self.load_state()
        if "settings" not in state or setting_name not in state["settings"]:
            return {"name": setting_name, "status": "missing"}
        del state["settings"][setting_name]
        self._write_state(state)
        return {"name": setting_name, "status": "restored", "value": None}

    def _write_state(self, state: Dict[str, Any]) -> None:
        self.defender_state_path.write_text(json.dumps(state, indent=2, sort_keys=True), encoding="utf-8")
