import json
from click.testing import CliRunner
import llm
from llm.cli import cli
import pytest

class MockModel(llm.Model):
    model_id = "mock"
    def execute(self, prompt, stream, response, conversation):
        return ["Hello ", "world!"]

@pytest.fixture(autouse=True)
def register_mock_model():
    class MockPlugin:
        @llm.hookimpl
        def register_models(self, register):
            register(MockModel())
    pm = llm.plugins.pm
    plugin = MockPlugin()
    pm.register(plugin)
    yield
    pm.unregister(plugin)

@pytest.fixture
def user_path(tmpdir):
    import os
    os.environ["LLM_USER_PATH"] = str(tmpdir)
    return tmpdir

def test_prompt_json(user_path):
    runner = CliRunner()
    result = runner.invoke(cli, ["prompt", "say hello", "-m", "mock", "--json"])
    assert result.exit_code == 0
    data = json.loads(result.output)
    
    assert isinstance(data, list)
    assert len(data) == 1
    assert "response" in data[0]
    assert data[0]["response"] == "Hello world!"
    assert "conversation_id" in data[0]
    assert data[0]["prompt"] == "say hello"

def test_prompt_json_no_log_error(user_path):
    runner = CliRunner()
    result = runner.invoke(cli, ["prompt", "say hello", "-m", "mock", "--json", "--no-log"])
    assert result.exit_code != 0
    assert "Cannot use --json with --no-log" in result.output

def test_prompt_json_no_stream(user_path):
    runner = CliRunner()
    result = runner.invoke(cli, ["prompt", "say hello", "-m", "mock", "--json", "--no-stream"])
    assert result.exit_code == 0
    data = json.loads(result.output)
    assert isinstance(data, list)
    assert "response" in data[0]
    assert data[0]["response"] == "Hello world!"
