"""Tests for output formatters."""

import json
import pytest
from opencypher_compliance.output import format_json, format_csv, format_console, write_output


@pytest.fixture
def sample_results():
    return {
        "metadata": {
            "database": "Test DB",
            "adapter": "bolt",
            "host": "localhost",
            "port": 7687,
            "database_version": "Neo4j/5.0",
            "spec_version": "9",
            "timestamp": "2026-03-13T14:30:00Z",
            "catalog_version": "1.0.0",
            "total_tests": 3,
            "passed": 2,
            "failed": 1,
            "pass_rate": "66.67%",
        },
        "summary_by_type": {
            "clause": {"total": 2, "passed": 1, "failed": 1, },
            "operator": {"total": 1, "passed": 1, "failed": 0, },
        },
        "results": [
            {"element": "MATCH", "type": "clause", "result": "pass", "duration_ms": 12},
            {"element": "MANDATORY MATCH", "type": "clause", "result": "fail",
             "error": "Not supported", "duration_ms": 3},
            {"element": "+", "type": "operator", "result": "pass", "duration_ms": 5},
        ],
    }


class TestFormatJson:
    def test_valid_json(self, sample_results):
        output = format_json(sample_results)
        parsed = json.loads(output)
        assert parsed["metadata"]["total_tests"] == 3
        assert len(parsed["results"]) == 3

    def test_contains_metadata(self, sample_results):
        output = format_json(sample_results)
        parsed = json.loads(output)
        assert "metadata" in parsed
        assert "summary_by_type" in parsed
        assert "results" in parsed


class TestFormatCsv:
    def test_header_row(self, sample_results):
        output = format_csv(sample_results)
        lines = output.strip().split("\n")
        assert lines[0] == "element,type,result,error,duration_ms"

    def test_data_rows(self, sample_results):
        output = format_csv(sample_results)
        lines = output.strip().split("\n")
        assert len(lines) == 4  # header + 3 results

    def test_error_in_csv(self, sample_results):
        output = format_csv(sample_results)
        assert "Not supported" in output


class TestFormatConsole:
    def test_contains_summary(self, sample_results):
        output = format_console(sample_results)
        assert "2 passed" in output
        assert "1 failed" in output
        assert "66.67%" in output

    def test_contains_type_breakdown(self, sample_results):
        output = format_console(sample_results)
        assert "clause" in output
        assert "operator" in output


class TestWriteOutput:
    def test_write_json(self, sample_results, tmp_path):
        files = write_output(sample_results, output_dir=tmp_path, format="json")
        assert len(files) == 1
        assert files[0].endswith(".json")
        content = json.loads(open(files[0]).read())
        assert content["metadata"]["total_tests"] == 3

    def test_write_csv(self, sample_results, tmp_path):
        files = write_output(sample_results, output_dir=tmp_path, format="csv")
        assert len(files) == 1
        assert files[0].endswith(".csv")

    def test_write_both(self, sample_results, tmp_path):
        files = write_output(sample_results, output_dir=tmp_path, format="both")
        assert len(files) == 2
        extensions = {f.split(".")[-1] for f in files}
        assert extensions == {"json", "csv"}

    def test_creates_directory(self, sample_results, tmp_path):
        out = tmp_path / "subdir" / "results"
        files = write_output(sample_results, output_dir=out, format="json")
        assert len(files) == 1
        assert out.exists()
