"""Tests for the dotprompt CLI."""

from unittest.mock import MagicMock

import pytest

from dotpromptz.cli import (
    _resolve_adapter,
    cli,
)

SIMPLE_PROMPT = """\
---
config:
  model: gpt-4o
input:
  schema:
    topic: string
---
Tell me about {{topic}}.
"""

PROMPT_WITH_INLINE_DATA = """\
---
config:
  model: gpt-4o
input:
  data:
    topic: AI
---
Tell me about {{topic}}.
"""


class TestCLIArguments:
    def test_no_arguments_shows_error(self, capsys: pytest.CaptureFixture[str]) -> None:
        with pytest.raises(SystemExit) as exc_info:
            cli([])
        assert exc_info.value.code == 2

    def test_nonexistent_file_shows_error(self, capsys: pytest.CaptureFixture[str]) -> None:
        with pytest.raises(SystemExit) as exc_info:
            cli(['/nonexistent/file.prompt'])
        assert exc_info.value.code == 2
        captured = capsys.readouterr()
        assert 'does not exist' in captured.err.lower() or 'exist' in captured.err.lower()

    def test_help_flag_works(self, capsys: pytest.CaptureFixture[str]) -> None:
        with pytest.raises(SystemExit) as exc_info:
            cli(['--help'])
        assert exc_info.value.code == 0
        captured = capsys.readouterr()
        assert 'run' in captured.out
        assert 'build' in captured.out
        assert '.prompt' in captured.out


class TestResolveAdapterCLIWrapper:
    """Tests that the CLI wrapper converts ValueError → sys.exit(2)."""

    def test_none_adapter_exits(self) -> None:
        mock_rendered = MagicMock()
        mock_rendered.adapter = None
        mock_rendered.config = {'model': 'gpt-4o'}

        with pytest.raises(SystemExit) as exc_info:
            _resolve_adapter(mock_rendered)
        assert exc_info.value.code == 2

    def test_no_adapter_no_model_exits(self) -> None:
        mock_rendered = MagicMock()
        mock_rendered.adapter = None
        mock_rendered.config = {}

        with pytest.raises(SystemExit) as exc_info:
            _resolve_adapter(mock_rendered)
        assert exc_info.value.code == 2
