"""Central configuration for version-dependent SAM model constants.

SAM2 (sam2 package) requires Python >= 3.10 and is unavailable on macOS
x86_64 (PyTorch dropped Intel Mac wheels after 2.2.2). On unsupported
platforms or Python 3.9, we fall back to SAM1 (segment-anything / ViT-B).

Exception: under Rosetta (x86_64 QGIS on Apple Silicon), the standalone
Python is downloaded as ARM64 3.10+, so SAM2 is available.
"""
from __future__ import annotations

import platform
import subprocess  # nosec B404
import sys


def _is_rosetta() -> bool:
    """Detect Rosetta 2 emulation (x86_64 process on Apple Silicon)."""
    if sys.platform != "darwin" or platform.machine() != "x86_64":
        return False
    try:
        result = subprocess.run(  # nosec B603 B607
            ["sysctl", "-n", "sysctl.proc_translated"],
            capture_output=True, text=True, encoding="utf-8", errors="replace",
            timeout=5,
        )
        return result.stdout.strip() == "1"
    except Exception:
        return False


IS_ROSETTA = _is_rosetta()

_IS_MACOS_X86 = (
    sys.platform == "darwin"
    and platform.machine() == "x86_64"  # noqa: W503
    and not IS_ROSETTA  # noqa: W503
)

# Under Rosetta, standalone Python will be ARM64 3.10+ -> SAM2
USE_SAM2 = (sys.version_info >= (3, 10) or IS_ROSETTA) and not _IS_MACOS_X86

# Intel Macs on QGIS 4 (Python 3.13+) cannot run local (Manual) inference: the
# Intel-Mac fallback pins the deep-learning runtime to its last Intel-Mac
# release (<=2.2.2), which ships no wheel for Python 3.13+, so the venv install
# would otherwise fail with a cryptic resolver error. The install gate reads
# this to fail fast and steer the user to Automatic (cloud) mode instead.
MACOS_X86_NO_LOCAL_INFERENCE = _IS_MACOS_X86 and sys.version_info >= (3, 13)

if USE_SAM2:
    SAM_PACKAGE = ("sam2", ">=1.0")
    TORCH_MIN = ">=2.5.1"
    TORCHVISION_MIN = ">=0.20.1"
    CHECKPOINT_URL = (
        "https://dl.fbaipublicfiles.com/segment_anything_2"
        "/092824/sam2.1_hiera_base_plus.pt"
    )
    CHECKPOINT_FILENAME = "sam2.1_hiera_base_plus.pt"
    # SHA256 hash for checkpoint verification (not a secret)
    CHECKPOINT_SHA256 = "a2345aede8715ab1d5d31b4a509fb160c5a4af1970f199d9054ccfb746c004c5"  # noqa: S105, E501  # pragma: allowlist secret
else:
    SAM_PACKAGE = ("segment-anything", ">=1.0")
    if _IS_MACOS_X86:
        TORCH_MIN = ">=2.0.0,<=2.2.2"
        TORCHVISION_MIN = ">=0.15.0,<=0.17.2"
    elif sys.version_info < (3, 10):
        # PyTorch dropped Python 3.9 support in 2.6.0; pin to last compatible release.
        TORCH_MIN = ">=2.0.0,<2.6.0"
        TORCHVISION_MIN = ">=0.15.0,<0.21.0"
    else:
        TORCH_MIN = ">=2.0.0"
        TORCHVISION_MIN = ">=0.15.0"
    CHECKPOINT_URL = (
        "https://dl.fbaipublicfiles.com/segment_anything"
        "/sam_vit_b_01ec64.pth"
    )
    CHECKPOINT_FILENAME = "sam_vit_b_01ec64.pth"
    # SHA256 hash for checkpoint verification (not a secret)
    CHECKPOINT_SHA256 = "ec2df62732614e57411cdcf32a23ffdf28910380d03139ee0f4fcbe91eb8c912"  # noqa: S105, E501  # pragma: allowlist secret


def macos_intel_unsupported_python() -> bool:
    """True on Intel (x86_64) macOS whose Python has no torch wheel.

    PyTorch's last Intel-mac release is 2.2.2, which ships cp38-cp312 wheels.
    On Python 3.13+ no wheel exists, so the long download then fails with
    "no matching distribution". Detect it up front to fail fast with a clear
    message instead of after a multi-minute download attempt.

    (Forcing an older standalone Python here would desync the in-process venv
    imports from QGIS's own interpreter; that fix waits for the import
    decoupling. Until then, this is a clean early stop.)
    """
    return _IS_MACOS_X86 and sys.version_info >= (3, 13)


# Known-good torch versions for Windows DLL fallback.
# Newer torch releases (2.10+) can fail with WinError 1114 / c10.dll
# on some Windows 10/11 machines. After a nuke-reinstall fails, we
# retry with these pinned versions.
if sys.platform == "win32":
    TORCH_WINDOWS_FALLBACK = "==2.5.1"
    TORCHVISION_WINDOWS_FALLBACK = "==0.20.1"
else:
    TORCH_WINDOWS_FALLBACK = None
    TORCHVISION_WINDOWS_FALLBACK = None
