from __future__ import annotations

import json
from typing import Any

import pytest
from typer.testing import CliRunner

import dr_llm.cli.query as query_cli
from dr_llm.cli import app
from dr_llm.providers.usage import TokenUsage
from tests.conftest import make_response

runner = CliRunner()


class _FakeAdapter:
    name = "openai"
    mode = "api"

    def generate(self, request: Any) -> Any:
        return make_response(
            text="hi",
            usage=TokenUsage(prompt_tokens=1, completion_tokens=2, total_tokens=3),
            provider="openai",
            model="gpt-4.1",
        )


class _FakeRegistry:
    def get(self, name: str) -> _FakeAdapter:
        return _FakeAdapter()

    def close(self) -> None:
        pass


def test_query_emits_response_json(monkeypatch: pytest.MonkeyPatch) -> None:
    monkeypatch.setattr(query_cli, "build_default_registry", _FakeRegistry)

    result = runner.invoke(
        app,
        [
            "query",
            "--provider",
            "openai",
            "--model",
            "gpt-4.1",
            "--message",
            "hello",
            "--no-record",
        ],
    )

    assert result.exit_code == 0
    payload = json.loads(result.stdout)
    assert payload["text"] == "hi"
    assert payload["usage"]["total_tokens"] == 3


def test_query_no_record_skips_db(monkeypatch: pytest.MonkeyPatch) -> None:
    """--no-record should never attempt to create a DB connection."""
    repo_created = False

    def _repo_should_not_be_called(*args: Any, **kwargs: Any) -> None:
        nonlocal repo_created
        repo_created = True

    monkeypatch.setattr(query_cli, "build_default_registry", _FakeRegistry)
    monkeypatch.setattr("dr_llm.cli.common._repo", _repo_should_not_be_called)

    result = runner.invoke(
        app,
        ["query", "--provider", "openai", "--model", "gpt-4.1", "--message", "hi", "--no-record"],
    )

    assert result.exit_code == 0
    assert not repo_created
