"""Tests for lapis_spec.cli."""

from __future__ import annotations

from pathlib import Path

import pytest
import yaml

from lapis_spec.cli import build_parser, main


class TestBuildParser:
    def test_required_args(self):
        parser = build_parser()
        with pytest.raises(SystemExit):
            parser.parse_args([])

    def test_input_output(self):
        parser = build_parser()
        args = parser.parse_args(["-i", "input.yaml", "-o", "output.lapis"])
        assert args.input == "input.yaml"
        assert args.output == "output.lapis"

    def test_long_args(self):
        parser = build_parser()
        args = parser.parse_args(["--input", "in.json", "--output", "out.lapis"])
        assert args.input == "in.json"
        assert args.output == "out.lapis"

    def test_no_validate_flag(self):
        parser = build_parser()
        args = parser.parse_args(["-i", "i.yaml", "-o", "o.lapis", "--no-validate"])
        assert args.no_validate is True

    def test_no_validate_default(self):
        parser = build_parser()
        args = parser.parse_args(["-i", "i.yaml", "-o", "o.lapis"])
        assert args.no_validate is False

    def test_version(self):
        parser = build_parser()
        with pytest.raises(SystemExit) as exc_info:
            parser.parse_args(["--version"])
        assert exc_info.value.code == 0


class TestMain:
    def test_file_not_found(self, tmp_path: Path):
        result = main(["-i", str(tmp_path / "nonexistent.yaml"), "-o", str(tmp_path / "out.lapis")])
        assert result == 1

    def test_invalid_extension(self, tmp_path: Path):
        bad_file = tmp_path / "data.txt"
        bad_file.write_text("{}")
        result = main(["-i", str(bad_file), "-o", str(tmp_path / "out.lapis")])
        assert result == 1

    def test_successful_conversion(self, tmp_path: Path, minimal_openapi: dict):
        input_file = tmp_path / "api.yaml"
        output_file = tmp_path / "api.lapis"
        input_file.write_text(yaml.dump(minimal_openapi), encoding="utf-8")
        result = main([
            "-i", str(input_file),
            "-o", str(output_file),
            "--no-validate",
        ])
        assert result == 0
        assert output_file.exists()
        content = output_file.read_text(encoding="utf-8")
        assert "[meta]" in content
        assert "api: Minimal API" in content

    def test_output_directory_created(self, tmp_path: Path, minimal_openapi: dict):
        input_file = tmp_path / "api.yaml"
        output_file = tmp_path / "sub" / "dir" / "api.lapis"
        input_file.write_text(yaml.dump(minimal_openapi), encoding="utf-8")
        result = main([
            "-i", str(input_file),
            "-o", str(output_file),
            "--no-validate",
        ])
        assert result == 0
        assert output_file.exists()

    def test_invalid_yaml(self, tmp_path: Path):
        bad_yaml = tmp_path / "bad.yaml"
        bad_yaml.write_text("openapi: 2.0\ninfo:\n  title: X", encoding="utf-8")
        result = main(["-i", str(bad_yaml), "-o", str(tmp_path / "out.lapis"), "--no-validate"])
        assert result == 1

    def test_no_validate_skips_validation(self, tmp_path: Path):
        input_file = tmp_path / "partial.yaml"
        doc = {
            "openapi": "3.0.3",
            "info": {"title": "Partial", "version": "0.1"},
            "paths": {},
        }
        input_file.write_text(yaml.dump(doc), encoding="utf-8")
        result = main([
            "-i", str(input_file),
            "-o", str(tmp_path / "out.lapis"),
            "--no-validate",
        ])
        assert result == 0
