import os
import numpy as np
import pytest
from dynasor.post_processing.filon import _alpha_beta_gamma_single, fourier_cos_filon


def test_abg():
    thetas = np.array([0.0, 3.14, -1, 0.5])

    # 3x4 due to historical reasons
    res = np.array([[0.00000000, 0.31830964, -0.03850188, 0.00536042],
                    [0.66666667, 0.40590123,  0.76525831, 0.69767347],
                    [1.33333333, 0.40590123,  1.20467472, 1.30029625]])

    new = np.array([_alpha_beta_gamma_single(t) for t in thetas])  # 4x3
    assert np.allclose(res, new.T)


def test_filon_regression():

    np.random.seed(42)
    ref = '0100010001000010111010111111110011101000001111101101010110000000'
    assert ''.join(map(str, np.random.choice([0, 1], 64))) == ref

    dt_list = [1.0, 1.234]
    Nt_list = [3, 5, 101]

    results = []

    for dt in dt_list:
        for Nt in Nt_list:
            w = np.arange(Nt) * np.pi/dt/(Nt-1)
            f = np.random.normal(size=(3, Nt))
            w2, F = fourier_cos_filon(f, dt)
            F /= 2
            assert np.allclose(w, w2)
            results.extend(F.flatten())

    this_dir = os.path.dirname(__file__)
    ref = np.load(os.path.join(this_dir, 'regression_results.npy'))
    # np.save(os.path.join(this_dir, 'regression_results.npy'), results)
    assert np.allclose(ref, np.array(results))


def test_value_error_bad_input():

    # 1-D array
    f = np.random.random((11,))
    with pytest.raises(ValueError):
        fourier_cos_filon(f, dt=1.0)

    # 3-D array
    f = np.random.random((11, 31, 5))
    with pytest.raises(ValueError):
        fourier_cos_filon(f, dt=1.0)

    # len of last axis is even number
    f = np.random.random((11, 30))
    with pytest.raises(ValueError):
        fourier_cos_filon(f, dt=1.0)

    # len of last axis is one
    f = np.random.random((11, 1))
    with pytest.raises(ValueError):
        fourier_cos_filon(f, dt=1.0)
