from __future__ import annotations

from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]
EXPECTED_STRUCTURED_NOTEBOOK_SOURCES = {
    "examples/01_foundations/01_dates_daycounts_and_calendars.py",
    "examples/01_foundations/02_numerical_methods_for_term_structures.py",
    "examples/02_curves/01_curve_construction_and_value_conversions.py",
    "examples/02_curves/02_curve_calibration_piecewise_and_global_fit.py",
    "examples/02_curves/03_curve_scenarios_key_rates_and_multicurve.py",
    "examples/03_bonds/01_fixed_rate_bonds_pricing_and_risk.py",
    "examples/03_bonds/02_floating_rate_notes_fixings_and_discount_margin.py",
    "examples/03_bonds/03_callable_puttable_and_sinking_fund_structures.py",
    "examples/04_analytics/01_yield_measures_and_yas.py",
    "examples/04_analytics/02_spread_toolkit_g_i_z_asw_oas.py",
    "examples/04_analytics/03_risk_hedging_and_var.py",
    "examples/05_portfolio/01_portfolio_summary_bucketing_and_liquidity.py",
    "examples/05_portfolio/02_benchmark_active_risk_and_attribution.py",
    "examples/05_portfolio/03_stress_testing_key_rate_profiles_and_scenarios.py",
    "examples/05_portfolio/04_etf_nav_basket_and_sec_yield.py",
    "examples/06_data_io/01_market_data_reference_data_and_pricing_specs.py",
    "examples/06_data_io/02_file_json_and_sqlite_workflows.py",
    "examples/07_engine/01_curve_builder_and_batch_pricing_router.py",
    "examples/07_engine/02_reactive_market_data_listener_and_scheduling.py",
    "examples/07_engine/03_end_to_end_research_pipeline.py",
}


def test_structured_example_catalog_matches_expected_20_notebooks() -> None:
    actual = {
        str(path.relative_to(ROOT))
        for path in sorted((ROOT / "examples").glob("[0-9][0-9]_*/*.py"))
    }
    assert actual == EXPECTED_STRUCTURED_NOTEBOOK_SOURCES


def test_examples_root_contains_no_legacy_flat_notebooks() -> None:
    top_level_py = sorted(path.name for path in (ROOT / "examples").glob("*.py") if path.name != "__init__.py")
    top_level_ipynb = sorted(path.name for path in (ROOT / "examples").glob("*.ipynb"))

    assert not top_level_py, f"Legacy flat python examples remain: {top_level_py}"
    assert not top_level_ipynb, f"Legacy flat notebooks remain: {top_level_ipynb}"


def test_structured_examples_do_not_import_removed_top_level_spreads_namespace() -> None:
    for path in sorted((ROOT / "examples").glob("[0-9][0-9]_*/*.py")):
        text = path.read_text(encoding="utf-8")
        assert "fuggers_py.spreads" not in text, f"{path} still imports the removed top-level spreads namespace"
