"""Ollama service discovery.

Detects a running Ollama instance and enumerates its models using
only stdlib ``urllib`` — no additional dependencies required.
"""

from __future__ import annotations

import json
import logging
import os
import urllib.error
import urllib.request

logger = logging.getLogger(__name__)

_DEFAULT_URL = "http://localhost:11434"


def get_ollama_base_url() -> str:
    """Resolve the Ollama server URL.

    Checks in order:

    1. ``[providers.ollama].base_url`` in ``~/.icarus/config.toml``
    2. ``OLLAMA_HOST`` environment variable
    3. Default ``http://localhost:11434``
    """
    # Config file takes priority — deferred import to avoid circular deps.
    from icarus.config.model_config import ModelConfig

    config = ModelConfig.load()
    config_url = config.get_base_url("ollama")
    if config_url:
        return config_url.rstrip("/")

    env_url = os.environ.get("OLLAMA_HOST")
    if env_url:
        return env_url.rstrip("/")

    return _DEFAULT_URL


def is_ollama_available(base_url: str = _DEFAULT_URL, timeout: float = 2.0) -> bool:
    """Check if an Ollama server is responding.

    ``GET /`` returns ``"Ollama is running"`` on a healthy instance.

    Args:
        base_url: Ollama server URL.
        timeout: Connection timeout in seconds (short to avoid blocking boot).

    Returns:
        True if the server responds, False on any error.
    """
    try:
        req = urllib.request.Request(f"{base_url}/", method="GET")
        with urllib.request.urlopen(req, timeout=timeout) as resp:
            return resp.status == 200
    except Exception:  # noqa: BLE001 — connection refused, timeout, etc.
        return False


def discover_ollama_models(
    base_url: str = _DEFAULT_URL, timeout: float = 5.0
) -> list[dict]:
    """Fetch the model list from a running Ollama server.

    ``GET /api/tags`` returns ``{"models": [...]}``.

    Args:
        base_url: Ollama server URL.
        timeout: Request timeout in seconds.

    Returns:
        List of dicts with keys ``name``, ``size``, ``parameter_size``,
        ``quantization_level``.  Returns an empty list on any error
        (connection refused, timeout, bad JSON, etc.) so callers don't
        need ``try/except``.
    """
    try:
        req = urllib.request.Request(f"{base_url}/api/tags", method="GET")
        with urllib.request.urlopen(req, timeout=timeout) as resp:
            data = json.loads(resp.read().decode("utf-8"))

        raw_models = data.get("models", [])
        result = []
        for m in raw_models:
            result.append({
                "name": m.get("name", ""),
                "size": m.get("size", 0),
                "parameter_size": m.get("details", {}).get("parameter_size", ""),
                "quantization_level": m.get("details", {}).get("quantization_level", ""),
            })
        return result
    except Exception:  # noqa: BLE001
        logger.debug("Ollama discovery failed at %s", base_url, exc_info=True)
        return []
