"""Focused tests for Fireworks AI first-class provider wiring.

These tests pin the wiring that makes Fireworks a real provider — alias
resolution through both CLI resolvers, config/doctor/overlay registration,
and credential/base-URL resolution — without
any live network calls.
"""

from __future__ import annotations

import contextlib
import io
import sys
import types
from argparse import Namespace

import pytest

if "dotenv" not in sys.modules:
    fake_dotenv = types.ModuleType("dotenv")
    fake_dotenv.load_dotenv = lambda *args, **kwargs: None
    sys.modules["dotenv"] = fake_dotenv

from hermes_cli.auth import resolve_api_key_provider_credentials
from hermes_cli.models import CANONICAL_PROVIDERS, _PROVIDER_LABELS, normalize_provider


@pytest.fixture(autouse=True)
def _clear_provider_env(monkeypatch):
    for key in ("FIREWORKS_API_KEY", "FIREWORKS_BASE_URL"):
        monkeypatch.delenv(key, raising=False)


class TestFireworksAliases:
    """Both CLI resolvers must map the aliases — the plugin's aliases= tuple is
    NOT consulted by these static maps, so they need explicit coverage."""

    @pytest.mark.parametrize("alias", ["fireworks", "fireworks-ai", "fw", "FW", " Fireworks-AI "])
    def test_models_normalize_provider(self, alias):
        assert normalize_provider(alias) == "fireworks"

    @pytest.mark.parametrize("alias", ["fireworks", "fireworks-ai", "fw"])
    def test_providers_normalize_provider(self, alias):
        from hermes_cli.providers import normalize_provider as normalize_in_providers

        assert normalize_in_providers(alias) == "fireworks"


class TestFireworksOrdering:
    """Fireworks participates in the canonical provider catalog."""

    def test_present_in_canonical_providers(self):
        slugs = [p.slug for p in CANONICAL_PROVIDERS]
        assert "fireworks" in slugs


    def test_has_a_label(self):
        assert _PROVIDER_LABELS.get("fireworks") == "Fireworks AI"


class TestFireworksConfigRegistry:
    def test_optional_env_vars_include_fireworks(self):
        from hermes_cli.config import OPTIONAL_ENV_VARS

        assert "FIREWORKS_API_KEY" in OPTIONAL_ENV_VARS
        assert OPTIONAL_ENV_VARS["FIREWORKS_API_KEY"]["category"] == "provider"
        assert OPTIONAL_ENV_VARS["FIREWORKS_API_KEY"]["password"] is True

        assert "FIREWORKS_BASE_URL" not in OPTIONAL_ENV_VARS


class TestFireworksOverlay:
    def test_overlay_exists(self):
        from hermes_cli.providers import HERMES_OVERLAYS

        assert "fireworks" in HERMES_OVERLAYS
        overlay = HERMES_OVERLAYS["fireworks"]
        assert overlay.transport == "openai_chat"
        assert overlay.base_url_override == "https://api.fireworks.ai/inference/v1"
        assert not overlay.base_url_env_var
        assert not overlay.is_aggregator


class TestFireworksDoctor:
    def test_provider_env_hints_include_fireworks(self):
        from hermes_cli.doctor import _PROVIDER_ENV_HINTS

        assert "FIREWORKS_API_KEY" in _PROVIDER_ENV_HINTS

    def test_slash_form_model_is_not_flagged_as_vendor_prefixed(self, monkeypatch, tmp_path):
        """Fireworks' native model IDs are slash-form (accounts/fireworks/...),
        so doctor must NOT warn that provider should be 'openrouter' / the prefix
        dropped — that heuristic is for aggregator vendor slugs only."""
        from hermes_cli import doctor as doctor_mod

        home = tmp_path / ".hermes"
        home.mkdir(parents=True)
        (home / "config.yaml").write_text(
            "model:\n"
            "  provider: fireworks\n"
            "  default: accounts/fireworks/models/kimi-k2p6\n"
            "memory: {}\n",
            encoding="utf-8",
        )
        (home / ".env").write_text("FIREWORKS_API_KEY=fw_test\n", encoding="utf-8")
        project = tmp_path / "project"
        project.mkdir()

        monkeypatch.setattr(doctor_mod, "HERMES_HOME", home)
        monkeypatch.setattr(doctor_mod, "PROJECT_ROOT", project)
        monkeypatch.setattr(doctor_mod, "_DHH", str(home))
        monkeypatch.setenv("FIREWORKS_API_KEY", "fw_test")

        # Keep the run offline and cheap.
        import httpx

        monkeypatch.setattr(httpx, "get", lambda *a, **k: types.SimpleNamespace(status_code=200))
        monkeypatch.setitem(
            sys.modules,
            "model_tools",
            types.SimpleNamespace(check_tool_availability=lambda *a, **k: ([], []), TOOLSET_REQUIREMENTS={}),
        )
        with contextlib.suppress(Exception):
            from hermes_cli import auth as _auth_mod

            monkeypatch.setattr(_auth_mod, "get_nous_auth_status", lambda: {})
            monkeypatch.setattr(_auth_mod, "get_codex_auth_status", lambda: {})

        buf = io.StringIO()
        with contextlib.suppress(SystemExit), contextlib.redirect_stdout(buf):
            doctor_mod.run_doctor(Namespace(fix=False))
        out = buf.getvalue()

        assert "vendor-prefixed" not in out
        assert "vendor/model slug" not in out


class TestFireworksCredentials:
    def test_resolves_default_base_url(self, monkeypatch):
        monkeypatch.setenv("FIREWORKS_API_KEY", "fw_test_key")
        creds = resolve_api_key_provider_credentials("fireworks")
        assert creds["api_key"] == "fw_test_key"
        assert creds["base_url"] == "https://api.fireworks.ai/inference/v1"

class TestFireworksAuxiliary:
    """resolve_provider_client wires the BYOK key and PAYG-safe aux model."""

    def _resolve(self, name):
        from unittest.mock import patch

        from agent.auxiliary_client import resolve_provider_client

        with patch("agent.auxiliary_client.OpenAI") as mock_openai:
            mock_openai.return_value = object()
            client, model = resolve_provider_client(name)
        return client, model, mock_openai.call_args.kwargs

    def test_client_has_no_partner_attribution_headers(self, monkeypatch):
        monkeypatch.setenv("FIREWORKS_API_KEY", "fw_test_key")
        client, model, kwargs = self._resolve("fireworks")
        assert client is not None
        headers = kwargs.get("default_headers", {})
        assert "HTTP-Referer" not in headers
        assert "X-Title" not in headers
        assert kwargs["base_url"] == "https://api.fireworks.ai/inference/v1"

    def test_aux_model_is_payg_safe(self, monkeypatch):
        monkeypatch.setenv("FIREWORKS_API_KEY", "fw_test_key")
        _, model, _ = self._resolve("fireworks")
        assert model.startswith("accounts/fireworks/models/")
        assert "/routers/" not in model
        assert "turbo" not in model.lower()

    def test_alias_resolves_through_aux_client(self, monkeypatch):
        monkeypatch.setenv("FIREWORKS_API_KEY", "fw_test_key")
        client, _, _ = self._resolve("fw")
        assert client is not None


class TestFireworksModelMetadata:
    def test_url_infers_fireworks(self):
        from agent.model_metadata import _infer_provider_from_url

        assert _infer_provider_from_url("https://api.fireworks.ai/inference/v1") == "fireworks"
