"""Tests for guardrails module."""

from __future__ import annotations

import threading

from liquid_mcp.guardrails import DailyLossTracker, check_max_order, min_token_amount


class TestCheckMaxOrder:
    def test_within_limit(self):
        assert check_max_order(500, 1000) is None

    def test_at_limit(self):
        assert check_max_order(1000, 1000) is None

    def test_exceeds_limit(self):
        err = check_max_order(1500, 1000)
        assert err is not None
        assert "1500" in err
        assert "1000" in err

    def test_below_minimum(self):
        err = check_max_order(5, 1000)
        assert err is not None
        assert "minimum" in err.lower()

    def test_at_minimum(self):
        assert check_max_order(10, 1000) is None


class TestDailyLossTracker:
    def test_no_losses(self):
        tracker = DailyLossTracker(5000)
        assert tracker.check() is None
        assert tracker.cumulative_loss == 0.0
        assert tracker.remaining == 5000.0

    def test_record_loss(self):
        tracker = DailyLossTracker(5000)
        tracker.record_loss(1000)
        assert tracker.cumulative_loss == 1000.0
        assert tracker.remaining == 4000.0
        assert tracker.check() is None

    def test_negative_loss_ignored(self):
        tracker = DailyLossTracker(5000)
        tracker.record_loss(-500)
        assert tracker.cumulative_loss == 0.0

    def test_limit_reached(self):
        tracker = DailyLossTracker(1000)
        tracker.record_loss(500)
        tracker.record_loss(500)
        err = tracker.check()
        assert err is not None
        assert "1000" in err

    def test_limit_exceeded(self):
        tracker = DailyLossTracker(1000)
        tracker.record_loss(1500)
        err = tracker.check()
        assert err is not None

    def test_thread_safety(self):
        """Concurrent record_loss calls should not lose data."""
        tracker = DailyLossTracker(100_000)
        num_threads = 10
        losses_per_thread = 100

        def record_losses():
            for _ in range(losses_per_thread):
                tracker.record_loss(1.0)

        threads = [threading.Thread(target=record_losses) for _ in range(num_threads)]
        for t in threads:
            t.start()
        for t in threads:
            t.join()

        assert tracker.cumulative_loss == num_threads * losses_per_thread


class TestMinTokenAmount:
    def test_normal_price(self):
        assert min_token_amount(50000.0) == 10.0 / 50000.0

    def test_zero_price(self):
        assert min_token_amount(0.0) == 0.0

    def test_negative_price(self):
        assert min_token_amount(-100.0) == 0.0
