"""Set / clear the Windows system-wide HTTP proxy via the registry + WinINet broadcast."""
from __future__ import annotations

import ctypes
import logging
import winreg

log = logging.getLogger(__name__)

_KEY_PATH = r"Software\Microsoft\Windows\CurrentVersion\Internet Settings"
_SETTINGS_CHANGED = 39
_REFRESH = 37


def _broadcast() -> None:
    """Tell running apps (browsers, etc.) that proxy settings changed."""
    try:
        inet = ctypes.windll.wininet  # type: ignore[attr-defined]
        inet.InternetSetOptionW(0, _SETTINGS_CHANGED, 0, 0)
        inet.InternetSetOptionW(0, _REFRESH, 0, 0)
    except Exception:
        pass


def set_system_proxy(host: str, port: int, bypass: str = "localhost;127.*;10.*;192.168.*;<local>") -> None:
    proxy = f"{host}:{port}"
    try:
        with winreg.OpenKey(
            winreg.HKEY_CURRENT_USER, _KEY_PATH, 0, winreg.KEY_SET_VALUE
        ) as key:
            winreg.SetValueEx(key, "ProxyEnable", 0, winreg.REG_DWORD, 1)
            winreg.SetValueEx(key, "ProxyServer", 0, winreg.REG_SZ, proxy)
            winreg.SetValueEx(key, "ProxyOverride", 0, winreg.REG_SZ, bypass)
        _broadcast()
        log.info("System proxy set to %s (bypass: %s)", proxy, bypass)
    except OSError:
        log.exception("Failed to set system proxy")


def clear_system_proxy() -> None:
    try:
        with winreg.OpenKey(
            winreg.HKEY_CURRENT_USER, _KEY_PATH, 0, winreg.KEY_SET_VALUE
        ) as key:
            winreg.SetValueEx(key, "ProxyEnable", 0, winreg.REG_DWORD, 0)
        _broadcast()
        log.info("System proxy cleared")
    except OSError:
        log.exception("Failed to clear system proxy")


def is_system_proxy_set() -> bool:
    try:
        with winreg.OpenKey(
            winreg.HKEY_CURRENT_USER, _KEY_PATH, 0, winreg.KEY_QUERY_VALUE
        ) as key:
            val, _ = winreg.QueryValueEx(key, "ProxyEnable")
            return val == 1
    except OSError:
        return False
