"""Tests for sre_beacon.cli."""

import os

import pytest
from click.testing import CliRunner

from sre_beacon.cli import main
from sre_beacon.demo import create_demo_data


@pytest.fixture
def runner():
    return CliRunner()


@pytest.fixture
def demo_files(tmp_path):
    return create_demo_data(str(tmp_path / "demo"))


class TestMainGroup:
    def test_version(self, runner):
        result = runner.invoke(main, ["--version"])
        assert result.exit_code == 0
        assert "1.0.0" in result.output

    def test_help(self, runner):
        result = runner.invoke(main, ["--help"])
        assert result.exit_code == 0
        assert "sre-beacon" in result.output


class TestSLOCommand:
    def test_slo_terminal(self, runner, demo_files):
        result = runner.invoke(main, ["slo", demo_files["slos"], demo_files["actuals"]])
        assert result.exit_code == 0
        assert "SLO Compliance" in result.output

    def test_slo_verbose(self, runner, demo_files):
        result = runner.invoke(main, ["slo", demo_files["slos"], demo_files["actuals"], "-v"])
        assert result.exit_code == 0
        assert "Error Budget Details" in result.output

    def test_slo_json_export(self, runner, demo_files, tmp_path):
        out = str(tmp_path / "slo.json")
        result = runner.invoke(main, ["slo", demo_files["slos"], demo_files["actuals"],
                                      "-f", "json", "-o", out])
        assert result.exit_code == 0
        assert os.path.exists(out)


class TestAvailabilityCommand:
    def test_availability_terminal(self, runner, demo_files):
        result = runner.invoke(main, ["availability", demo_files["availability"]])
        assert result.exit_code == 0
        assert "Availability Report" in result.output

    def test_availability_verbose(self, runner, demo_files):
        result = runner.invoke(main, ["availability", demo_files["availability"], "-v"])
        assert result.exit_code == 0
        assert "Nines Comparison" in result.output


class TestIncidentsCommand:
    def test_incidents_terminal(self, runner, demo_files):
        result = runner.invoke(main, ["incidents", demo_files["incidents"]])
        assert result.exit_code == 0
        assert "Incident Analysis" in result.output
        assert "MTTR" in result.output

    def test_incidents_verbose(self, runner, demo_files):
        result = runner.invoke(main, ["incidents", demo_files["incidents"], "-v"])
        assert result.exit_code == 0
        assert "By Service" in result.output

    def test_incidents_json(self, runner, demo_files, tmp_path):
        out = str(tmp_path / "incidents.json")
        result = runner.invoke(main, ["incidents", demo_files["incidents"], "-f", "json", "-o", out])
        assert result.exit_code == 0
        assert os.path.exists(out)


class TestToilCommand:
    def test_toil_terminal(self, runner, demo_files):
        result = runner.invoke(main, ["toil", demo_files["toil"]])
        assert result.exit_code == 0
        assert "Toil Analysis" in result.output

    def test_toil_verbose(self, runner, demo_files):
        result = runner.invoke(main, ["toil", demo_files["toil"], "-v"])
        assert result.exit_code == 0
        assert "All Tasks" in result.output


class TestAlertsCommand:
    def test_alerts_terminal(self, runner, demo_files):
        result = runner.invoke(main, ["alerts", demo_files["alerts"]])
        assert result.exit_code == 0
        assert "Alert Rule Audit" in result.output

    def test_alerts_verbose(self, runner, demo_files):
        result = runner.invoke(main, ["alerts", demo_files["alerts"], "-v"])
        assert result.exit_code == 0
        assert "Issues" in result.output

    def test_alerts_fail_on_critical(self, runner, demo_files):
        result = runner.invoke(main, ["alerts", demo_files["alerts"], "--fail-on", "critical"])
        assert result.exit_code == 1

    def test_alerts_json(self, runner, demo_files, tmp_path):
        out = str(tmp_path / "alerts.json")
        result = runner.invoke(main, ["alerts", demo_files["alerts"], "-f", "json", "-o", out])
        assert result.exit_code == 0
        assert os.path.exists(out)

    def test_alerts_html(self, runner, demo_files, tmp_path):
        out = str(tmp_path / "alerts.html")
        result = runner.invoke(main, ["alerts", demo_files["alerts"], "-f", "html", "-o", out])
        assert result.exit_code == 0
        assert os.path.exists(out)


class TestMaturityCommand:
    def test_maturity_terminal(self, runner, demo_files):
        result = runner.invoke(main, ["maturity", demo_files["maturity"]])
        assert result.exit_code == 0
        assert "SRE Maturity" in result.output

    def test_maturity_verbose(self, runner, demo_files):
        result = runner.invoke(main, ["maturity", demo_files["maturity"], "-v"])
        assert result.exit_code == 0
        assert "SLO Adoption" in result.output


class TestDemoCommand:
    def test_demo(self, runner, tmp_path):
        result = runner.invoke(main, ["demo", "-d", str(tmp_path / "demo-out")])
        assert result.exit_code == 0
        assert "Demo complete" in result.output

    def test_demo_verbose(self, runner, tmp_path):
        result = runner.invoke(main, ["demo", "-v", "-d", str(tmp_path / "demo-v")])
        assert result.exit_code == 0
        assert "Demo complete" in result.output


class TestRulesCommand:
    def test_rules(self, runner):
        result = runner.invoke(main, ["rules"])
        assert result.exit_code == 0
        assert "SRE-ALT-001" in result.output
        assert "15 rules" in result.output
