import sys
import unittest
from pathlib import Path

import pandas as pd

SCRIPTS_DIR = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(SCRIPTS_DIR))

import liquidity_capacity as mod  # noqa: E402


class MaxNotionalTest(unittest.TestCase):
    """The wallet cap looks like the binding limit but never is — capacity depends on it."""

    def test_risk_sizing_binds_before_the_wallet_cap(self):
        fraction, cap_binds = mod.max_notional_wallet_fraction(0.0075, 0.05, 2.0, 0.18)
        # 0.0075/0.05 = 15% margin < 18% cap, so the cap is dead weight post-RiskCap.
        self.assertFalse(cap_binds)
        self.assertAlmostEqual(fraction, 0.30)

    def test_wallet_cap_binds_again_if_risk_budget_is_raised(self):
        """Raising risk_per_trade past cap*hard_stop silently re-arms the wallet cap."""
        fraction, cap_binds = mod.max_notional_wallet_fraction(0.02, 0.05, 2.0, 0.18)
        self.assertTrue(cap_binds)
        self.assertAlmostEqual(fraction, 0.36)

    def test_capacity_scales_inversely_with_notional_fraction(self):
        """Halving per-trade size doubles the account the same liquidity supports."""
        small, _ = mod.max_notional_wallet_fraction(0.00375, 0.05, 2.0, 0.18)
        big, _ = mod.max_notional_wallet_fraction(0.0075, 0.05, 2.0, 0.18)
        self.assertAlmostEqual(big / small, 2.0)


class QuoteVolumeTest(unittest.TestCase):
    def test_converts_base_volume_to_quote_notional(self):
        """Feather volume is base; using it raw would misprice caps by the pair price."""
        frame = pd.DataFrame({"volume": [1_000.0, 500.0], "close": [0.08, 0.10]})
        self.assertEqual(list(mod.quote_volume(frame)), [80.0, 50.0])


class PairPathTest(unittest.TestCase):
    def test_maps_perp_pair_to_feather_name(self):
        self.assertEqual(
            mod.pair_to_feather(Path("/d"), "POWER/USDT:USDT").name,
            "POWER_USDT_USDT-5m-futures.feather",
        )


class PairCapacityTest(unittest.TestCase):
    def test_missing_feather_returns_none_rather_than_a_cap(self):
        """A silent zero here would read as 'unlimited capacity' downstream."""
        self.assertIsNone(mod.pair_capacity(Path("/nonexistent"), "POWER/USDT:USDT", 90))


class EntryAnchorTest(unittest.TestCase):
    def test_entry_time_snaps_back_to_its_own_bar(self):
        """Entries fire seconds after a close; rounding forward would read the next bar."""
        from datetime import datetime, timezone

        self.assertEqual(
            mod.floor5(datetime(2026, 7, 15, 12, 34, 59, tzinfo=timezone.utc)),
            datetime(2026, 7, 15, 12, 30, tzinfo=timezone.utc),
        )


if __name__ == "__main__":
    unittest.main()
