#
#   Imandra Inc.
#
#   update_check.py - Non-blocking update check against PyPI
#

import json
import os
import sys
import time
from pathlib import Path

_CACHE_DIR = (
    Path(os.environ.get('XDG_CACHE_HOME', Path.home() / '.cache')) / 'codelogician'
)
_CACHE_FILE = _CACHE_DIR / 'update-check.json'
_CHECK_INTERVAL = 86400  # 24 hours
_PYPI_URL = 'https://pypi.org/pypi/codelogician/json'
_REQUEST_TIMEOUT = 2  # seconds


def _read_cache() -> dict | None:
    try:
        data = json.loads(_CACHE_FILE.read_text())
        if time.time() - data.get('last_check', 0) < _CHECK_INTERVAL:
            return data
    except Exception:
        pass
    return None


def _write_cache(latest_version: str) -> None:
    try:
        _CACHE_DIR.mkdir(parents=True, exist_ok=True)
        _CACHE_FILE.write_text(
            json.dumps({'last_check': time.time(), 'latest_version': latest_version})
        )
    except Exception:
        pass


def _fetch_latest_version() -> str | None:
    try:
        from urllib.request import Request, urlopen

        req = Request(_PYPI_URL, headers={'Accept': 'application/json'})
        with urlopen(req, timeout=_REQUEST_TIMEOUT) as resp:
            data = json.loads(resp.read())
            return data['info']['version']
    except Exception:
        return None


def _parse_version(v: str) -> tuple:
    """Simple version tuple for comparison, ignoring pre-release suffixes."""
    import re

    match = re.match(r'(\d+(?:\.\d+)*)', v)
    if not match:
        return (0,)
    return tuple(int(x) for x in match.group(1).split('.'))


def check_for_update() -> None:
    """Print a notice to stderr if a newer version is available on PyPI.

    - Checks at most once per 24 hours (cached in ~/.cache/codelogician/)
    - Never blocks for more than 2 seconds
    - Silently does nothing on any error
    - Disabled by setting CODELOGICIAN_NO_UPDATE_CHECK=1
    """
    if os.environ.get('CODELOGICIAN_NO_UPDATE_CHECK', '') == '1':
        return

    try:
        from codelogician import __version__

        current = __version__

        # Try cache first
        cache = _read_cache()
        if cache is not None:
            latest = cache.get('latest_version', '')
        else:
            latest = _fetch_latest_version()
            if latest:
                _write_cache(latest)

        if not latest:
            return

        if _parse_version(latest) > _parse_version(current):
            print(
                f'\n  Update available: {current} → {latest}'
                f'    Run: uv tool upgrade codelogician\n',
                file=sys.stderr,
            )
    except Exception:
        pass
