import pytest
import importlib
code = importlib.import_module('utils')
import numpy as np

@pytest.fixture
def netcdf_data():
    return '/data/products/median/netcdf/20220801_3H_MEDIAN.nc'

def test_concat_dataframes():
    assert code.concat_dataframes('expect_fail', ['AUG', 'SEP'], 'OD550_DUST', None, None) == (None, None)
#needs more tests

def test_retrieve_single_point_1(netcdf_data):
    result =  np.float32(0.031516124)
    assert code.retrieve_single_point(netcdf_data, 1, 45, 45, 'OD550_DUST') == result

def test_retrieve_single_point_2(netcdf_data):
    result =  np.float32(0.00066542445)
    assert code.retrieve_single_point(netcdf_data, 9, 145, -45, 'OD550_DUST') == result

def test_retrieve_single_point_3(netcdf_data):
    result =  np.float32(0.00046437158)
    assert code.retrieve_single_point(netcdf_data, 1, -5, 175, 'OD550_DUST') == result

def test_retrieve_timeseries_1(netcdf_data):
    run = code.retrieve_timeseries(netcdf_data, 0, 0, 'OD550_DUST' , method='netcdf', forecast=False)
    assert run[0] == 0.25

def test_retrieve_timeseries_2(netcdf_data):
    run = code.retrieve_timeseries(netcdf_data, 45, 35, 'OD550_DUST' , method='netcdf', forecast=False)
    assert run[0] == 45.25

def test_retrieve_timeseries_3(netcdf_data):
    run = code.retrieve_timeseries(netcdf_data, 0, 0, 'OD550_DUST' , method='netcdf', forecast=False)
    assert run[-1][1].description == 'Dust AOD at 550 nm'

def test_find_nearest():
    lst = np.array([-7.75, -6.25, -3, -1, 0, 1, 3.35, 5, 7])
    target = 2.5
    assert code.find_nearest(lst, target) == 3.35

    lst = np.array([-7.75, -6.25, -3, -1, 0, 1, 3.35, 5, 7])
    target = -5
    assert code.find_nearest(lst, target) == -6.25

    target = -50
    assert code.find_nearest(lst, target) == -7.75

# NOT USED
# def find_nearest2(array, value):

def test_calc_matrix():
    assert code.calc_matrix(0) == (1, 0)
    assert code.calc_matrix(1) == (1, 1)
    assert code.calc_matrix(2) == (2, 1)
    assert code.calc_matrix(3) == (2, 2)
    assert code.calc_matrix(4) == (2, 2)
    assert code.calc_matrix(5) == (3, 2)
    assert code.calc_matrix(6) == (3, 2)
    assert code.calc_matrix(9) == (3, 3)
    assert code.calc_matrix(12) == (4, 3)

def test_magnitude():
    assert code.magnitude(0)==0
    assert code.magnitude(1)==0
    assert code.magnitude(12)==1
    assert code.magnitude(20)==1
    assert code.magnitude(21)==1
    assert code.magnitude(211)==2
    assert code.magnitude(3112)==3
    assert code.magnitude(31124)==4

def test_normalize_vals():
    bounds = [-0.1, -0.08, -0.06, -0.04, -0.02, 0., 0.02, 0.04, 0.06, 0.08, 0.1]
    bounds = np.array(bounds).astype('float32')
    result = [0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ]
    magn = code.magnitude(bounds[-1])
    n_bounds = code.normalize_vals(bounds, bounds[0], bounds[-1], magn)
    assert np.array_equiv(n_bounds, np.array(result).astype('float32'))

    bounds = [0., 0.2, 0.4, 0.6, 0.8, 1., 1.2, 1.4, 1.6, 1.8, 2.]
    bounds = np.array(bounds).astype('float32')
    result = [0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ]
    magn = code.magnitude(bounds[-1])
    n_bounds = code.normalize_vals(bounds, bounds[0], bounds[-1], magn)
    assert np.array_equiv(n_bounds, np.array(result).astype('float32'))

def test_get_colorscale():
    bounds1 = [-0.1, -0.08, -0.06, -0.04, -0.02, 0., 0.02, 0.04, 0.06, 0.08, 0.1]
    bounds2 = [0., 0.2, 0.4, 0.6, 0.8, 1., 1.2, 1.4, 1.6, 1.8, 2.]
    color1 = 'viridis'
    color2 = 'RdBu_r'
    assert code.get_colorscale(bounds1, color1, True)[0] == [0.0, 'rgba(68, 1, 84, 255)']
    assert code.get_colorscale(bounds2, color2, True)[0] == [0.0, 'rgba(5, 48, 97, 255)']

def test_get_vis_edate():
    assert code.get_vis_edate('20220808', hour=0) == ('20220807', 12)
    assert code.get_vis_edate('20220808', hour=1) == ('20220807', 12)
    assert code.get_vis_edate('20220809', hour=3) == ('20220808', 18)
    assert code.get_vis_edate('20220609', hour=12) == ('20220609', 0)
    assert code.get_vis_edate('20220609', hour=33) == ('20220610', 0)
    assert code.get_vis_edate('20220609', hour=72) == ('20220611', 12)
