"""Tests for credit export-regulatory and regulatory-export CLI subcommands."""

from __future__ import annotations

import json
import os
import tempfile
from io import StringIO
from unittest.mock import patch

from orxaq.experiences.cli import main

_CECL_BASE = ["credit", "export-regulatory", "--framework", "cecl"]
_CCAR_BASE = ["credit", "export-regulatory", "--framework", "ccar"]


class TestCreditExportRegulatoryCLI:
    """Test `orxaq credit export-regulatory` subcommand (RegulatoryExporter)."""

    def test_cecl_json_exit_zero(self) -> None:
        buf = StringIO()
        with patch("sys.stdout", buf):
            rc = main([*_CECL_BASE])
        assert rc == 0

    def test_cecl_json_framework_field(self) -> None:
        buf = StringIO()
        with patch("sys.stdout", buf):
            main([*_CECL_BASE])
        data = json.loads(buf.getvalue())
        assert data["framework"] == "CECL"

    def test_cecl_json_has_institution_id(self) -> None:
        buf = StringIO()
        with patch("sys.stdout", buf):
            main([*_CECL_BASE, "--institution-id", "BANK42"])
        data = json.loads(buf.getvalue())
        assert data["institution_id"] == "BANK42"

    def test_cecl_json_has_quantitative_results(self) -> None:
        buf = StringIO()
        with patch("sys.stdout", buf):
            main([*_CECL_BASE])
        data = json.loads(buf.getvalue())
        assert "quantitative_results" in data
        assert "ecl_estimate" in data["quantitative_results"]

    def test_cecl_json_is_serializable(self) -> None:
        buf = StringIO()
        with patch("sys.stdout", buf):
            main([*_CECL_BASE])
        data = json.loads(buf.getvalue())
        assert isinstance(data, dict)

    def test_ccar_json_exit_zero(self) -> None:
        buf = StringIO()
        with patch("sys.stdout", buf):
            rc = main([*_CCAR_BASE])
        assert rc == 0

    def test_ccar_json_framework_field(self) -> None:
        buf = StringIO()
        with patch("sys.stdout", buf):
            main([*_CCAR_BASE])
        data = json.loads(buf.getvalue())
        assert data["framework"] == "CCAR"

    def test_ccar_json_has_scenario_results(self) -> None:
        buf = StringIO()
        with patch("sys.stdout", buf):
            main([*_CCAR_BASE])
        data = json.loads(buf.getvalue())
        assert "scenario_results" in data
        assert isinstance(data["scenario_results"], list)
        assert len(data["scenario_results"]) > 0

    def test_ccar_json_each_scenario_has_ecl(self) -> None:
        buf = StringIO()
        with patch("sys.stdout", buf):
            main([*_CCAR_BASE])
        data = json.loads(buf.getvalue())
        for sr in data["scenario_results"]:
            assert "ecl" in sr
            assert isinstance(sr["ecl"], float)

    def test_cecl_markdown_exit_zero(self) -> None:
        buf = StringIO()
        with patch("sys.stdout", buf):
            rc = main([*_CECL_BASE, "--format", "markdown"])
        assert rc == 0
        assert len(buf.getvalue()) > 0

    def test_cecl_markdown_has_cecl_header(self) -> None:
        buf = StringIO()
        with patch("sys.stdout", buf):
            main([*_CECL_BASE, "--format", "markdown"])
        assert "CECL" in buf.getvalue()

    def test_output_file_created(self) -> None:
        with tempfile.NamedTemporaryFile(suffix=".json", delete=False) as f:
            path = f.name
        try:
            with patch("sys.stderr", StringIO()):
                rc = main([*_CECL_BASE, "--output", path])
            assert rc == 0
            assert os.path.exists(path)
            with open(path) as fh:
                data = json.loads(fh.read())
            assert data["framework"] == "CECL"
        finally:
            os.unlink(path)
