"""Tests for belief-volatility surface engine (Rust)."""

import pytest
import horizon as hz


class TestBeliefVolSurface:
    def test_init_state(self):
        s = hz.BeliefVolSurface()
        assert s.current_vol() > 0.0
        assert 0.0 < s.jump_probability() < 1.0

    def test_convergence_from_stable_data(self):
        s = hz.BeliefVolSurface(decay=0.99, min_observations=5)
        for i in range(50):
            price = 0.50 + 0.001 * (i % 3 - 1)
            s.update(price, float(i), 0.49, 0.51, 100.0)
        vol = s.current_vol()
        assert vol < 1.0
        assert vol > 0.0

    def test_jump_detection(self):
        s = hz.BeliefVolSurface(decay=0.99, min_observations=5)
        # Feed stable prices
        for i in range(30):
            s.update(0.50, float(i), 0.49, 0.51, 100.0)
        # Then a big jump
        s.update(0.80, 30.0, 0.79, 0.81, 100.0)
        # Jump probability should remain meaningful
        jp = s.jump_probability()
        assert 0.0 < jp < 1.0

    def test_surface_point_positive(self):
        s = hz.BeliefVolSurface(decay=0.99, min_observations=5)
        for i in range(10):
            s.update(0.50 + 0.01 * i, float(i), 0.0, 0.0, 0.0)
        assert s.surface_point(1.0) > 0.0

    def test_surface_point_scales_with_time(self):
        s = hz.BeliefVolSurface(decay=0.99, min_observations=5)
        for i in range(20):
            s.update(0.50 + 0.005 * (i % 4 - 2), float(i), 0.48, 0.52, 100.0)
        short = s.surface_point(0.1)
        long = s.surface_point(10.0)
        assert long > short

    def test_reset(self):
        s = hz.BeliefVolSurface(decay=0.99, min_observations=5)
        for i in range(20):
            s.update(0.50, float(i), 0.0, 0.0, 0.0)
        s.reset()
        vol = s.current_vol()
        assert vol > 0.0  # back to initial default

    def test_repr(self):
        s = hz.BeliefVolSurface()
        assert "BeliefVolSurface" in repr(s)

    def test_custom_params(self):
        s = hz.BeliefVolSurface(decay=0.95, min_observations=3)
        for i in range(10):
            s.update(0.50 + 0.02 * (i % 2), float(i), 0.48, 0.52, 50.0)
        assert s.current_vol() > 0.0

    def test_no_bid_ask(self):
        # Should work without bid/ask data
        s = hz.BeliefVolSurface(decay=0.99, min_observations=5)
        for i in range(10):
            s.update(0.50 + 0.01 * i, float(i))
        assert s.current_vol() > 0.0
