from __future__ import annotations

from argparse import Namespace

import pytest

from blackbox.cli import main, parse_args, run


class TestParseArgs:
    def test_serve_defaults(self) -> None:
        args = parse_args(["serve"]).unwrap()
        assert "serve" == args.command
        assert 7100 == args.port
        assert args.no_open is False

    def test_serve_custom_port(self) -> None:
        args = parse_args(["serve", "--port", "8080"]).unwrap()
        assert 8080 == args.port

    def test_serve_no_open(self) -> None:
        args = parse_args(["serve", "--no-open"]).unwrap()
        assert args.no_open is True

    def test_no_command_errors(self) -> None:
        with pytest.raises(SystemExit):
            parse_args([])


class TestRun:
    def test_serve_launches_uvicorn(self, monkeypatch: pytest.MonkeyPatch) -> None:
        called_with: dict[str, object] = {}

        def fake_uvicorn_run(app: object, **kwargs: object) -> None:
            called_with["app"] = app
            called_with.update(kwargs)

        monkeypatch.setattr("uvicorn.run", fake_uvicorn_run)
        args = parse_args(["serve", "--no-open"]).unwrap()
        run(args).unwrap()
        assert "127.0.0.1" == called_with["host"]
        assert 7100 == called_with["port"]

    def test_unknown_command(self) -> None:
        args = Namespace(command="bogus")
        result = run(args)
        assert not result.is_ok()


class TestMain:
    def test_main_serve(self, monkeypatch: pytest.MonkeyPatch) -> None:
        monkeypatch.setattr("sys.argv", ["blackbox", "serve", "--no-open"])
        monkeypatch.setattr("uvicorn.run", lambda *a, **kw: None)
        main()
