"""Tests for Bootstrap Amplification."""

import numpy as np
import pytest

from tqce.amplification.amplifier import BootstrapAmplifier


class TestBootstrapAmplifier:
    def test_amplify_returns_correct_shape(self):
        amp = BootstrapAmplifier(signal_dim=8)
        signal = np.random.randn(8) * 0.01
        result, stats = amp.amplify(signal)
        assert result.shape == (8,)

    def test_amplification_factor_positive(self):
        amp = BootstrapAmplifier(signal_dim=4, amplification_target=5.0)
        signal = np.random.randn(4) * 0.1
        _, stats = amp.amplify(signal)
        assert stats["amplification_factor"] > 0

    def test_amplification_near_target(self):
        np.random.seed(42)
        target = 10.0
        amp = BootstrapAmplifier(
            signal_dim=4, amplification_target=target, stability_coefficient=0.9
        )
        signal = np.ones(4) * 0.1
        result, stats = amp.amplify(signal, max_iterations=500)
        assert stats["amplification_factor"] > 1.0

    def test_convergence(self):
        np.random.seed(42)
        amp = BootstrapAmplifier(signal_dim=4, amplification_target=5.0)
        signal = np.ones(4) * 0.1
        _, stats = amp.amplify(signal, max_iterations=500)
        assert stats["converged"] or stats["iterations"] == 500

    def test_stats_keys(self):
        amp = BootstrapAmplifier(signal_dim=4)
        _, stats = amp.amplify(np.ones(4) * 0.1)
        expected = {
            "amplification_factor", "iterations", "converged",
            "amplification_history"
        }
        assert set(stats.keys()) == expected

    def test_zero_signal_no_crash(self):
        amp = BootstrapAmplifier(signal_dim=4)
        result, stats = amp.amplify(np.zeros(4))
        assert np.all(np.isfinite(result))

    def test_learn_resonance(self):
        np.random.seed(42)
        amp = BootstrapAmplifier(signal_dim=4, amplification_target=5.0)
        signals = np.random.randn(5, 4) * 0.1
        amp.learn_resonance(signals, n_epochs=3)
        eigvals = np.linalg.eigvals(amp.loop_kernel)
        assert np.max(np.abs(eigvals)) <= amp.stability_coefficient + 0.01
