import pytest
import importlib
code = importlib.import_module('data_handler')
from data_handler import START_DATE
from data_handler import END_DATE
from data_handler import OBS

@pytest.fixture
def aeronet_instance():
    return code.Observations1dHandler('20220404','20220405' , 'aeronet') 

def test_generate_obs1d_tstep_trace1(aeronet_instance):
    run = aeronet_instance.generate_obs1d_tstep_trace('OD550_DUST')
    assert str(type(run[1])) == "<class 'dash_leaflet.GeoJSON.GeoJSON'>"
    assert run[0].shape ==(120, 3)

# @pytest.fixture 
# def obsTSHandler_instance():
#     return code.ObsTimeSeriesHandler('aeronet','20220404','20220405', 'OD550_DUST', ['median', 'monarch']) 
#
# def test_retrieve_timeseries():
#     assert obsTSHandler_instance.retrieve_timeseries(idx, st_name, model) == 'hello'

    
# =================== TIME SERIES HANDLER ============================
@pytest.fixture
def TSHandler():
    return code.TimeSeriesHandler('median', '20220606', 'OD550_DUST')

def test_TimeSeriesHandler(TSHandler):
    run = TSHandler.retrieve_single_point(1, 45, 45, model='median')
    assert float(run) == 0.10633552074432373

def test_TimeSeriesHandler_1(TSHandler):
    run = TSHandler.retrieve_single_point(3, 5, 5, model=None)
    assert float(run) == 0.00830854382365942

def test_retrieve_timeseries(TSHandler):
    run = TSHandler.retrieve_timeseries(5, 5, model=None, method='netcdf', forecast=False)
    assert run.layout.title.text =='Dust Optical Depth @ lat = 5 and lon = 5'

def test_retrieve_timeseries_1(TSHandler):
    run = TSHandler.retrieve_timeseries(35, 15, model='monarch', method='netcdf', forecast=True)
    assert run.layout.title.text =='Dust Optical Depth @ lat = 35 and lon = 15'

def test_retrieve_timeseries_2(TSHandler):
    run = TSHandler.retrieve_timeseries(35, 15, model='monarch', method='netcdf', forecast=True)
    assert run.data[0].name == 'MULTI-MODEL (35.25, 15.25)'

# =================== FIGURE HANDLER ============================
@pytest.fixture
def FigureHandler():
    return code.FigureHandler('median', '20220606')

def test_FH_get_center(FigureHandler):
    assert FigureHandler.get_center([35,45]) == [35, 45]
    assert FigureHandler.get_center([-35,-45]) == [-35, -45]
    assert FigureHandler.get_center() == [43.25, 16.5]


def test_set_data_AOD(FigureHandler):
    assert len(FigureHandler.set_data('OD550_DUST', tstep=0)[0]) == 22620
    assert FigureHandler.set_data('OD550_DUST', tstep=0)[0][0] == -26.75

    assert len(FigureHandler.set_data('OD550_DUST', tstep=3)[0]) == 22620
    assert FigureHandler.set_data('OD550_DUST', tstep=3)[0][0] == -26.75

def test_set_data_SCONC(FigureHandler):
    assert len(FigureHandler.set_data('SCONC_DUST', tstep=0)[0]) == 22620
    assert FigureHandler.set_data('SCONC_DUST', tstep=0)[0][0] == -26.75


def test_retrieve_cdatetime(FigureHandler):
    assert str(FigureHandler.retrieve_cdatetime(tstep=0)) == '2022-06-06 12:00:00'
    assert str(FigureHandler.retrieve_cdatetime(tstep=6)) == '2022-06-07 06:00:00'
    assert str(FigureHandler.retrieve_cdatetime(tstep=12)) == '2022-06-08 00:00:00'

def test_generate_contour_tstep_trace_leaflet(FigureHandler):
    result = "GeoJSON(hideout={'colorscale': ['rgba(255,255,255,0.4)', '#a1ede3', '#5ce3ba', '#fcd775', '#da7230', '#9e6226', '#714921', '#392511', '#1d1309'], 'bounds': array([ 0. ,  0.1,  0.2,  0.4,  0.8,  1.2,  1.6,  3.2,  6.4, 10. ]"
    assert result in str(FigureHandler.generate_contour_tstep_trace_leaflet('OD550_DUST', tstep=0)[0])
    result2 = "Colorbar(classes=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], colorscale=['rgba(255,255,255,0.4)', '#a1ede3', '#5ce3ba', '#fcd775', '#da7230', '#9e6226', '#714921', '#392511', '#1d1309']"
    assert result2 in str(FigureHandler.generate_contour_tstep_trace_leaflet('OD550_DUST', tstep=0)[1])

def test_generate_contour_tstep_trace_AOD(FigureHandler):
    assert FigureHandler.generate_contour_tstep_trace('OD550_DUST', tstep=0)['name'] == 'Dust Optical Depth_contours'
    assert FigureHandler.generate_contour_tstep_trace('OD550_DUST', tstep=0)['showlegend'] == False

def test_generate_contour_tstep_trace_SCONC(FigureHandler):
    assert FigureHandler.generate_contour_tstep_trace('SCONC_DUST', tstep=0)['name'] == 'Dust Surface Conc. (µg/m³)_contours'
    assert FigureHandler.generate_contour_tstep_trace('SCONC_DUST', tstep=0)['showlegend'] == False

def test_generate_var_tstep_trace_leaflet_AOD(FigureHandler):
    assert str(FigureHandler.generate_var_tstep_trace_leaflet(varname='OD550_DUST', tstep=0))[0:200] == "GeoJSON(data={'type': 'FeatureCollection', 'features': [{'type': 'Feature', 'geometry': {'type': 'Point', 'coordinates': [-26.75, 0.25]}, 'properties': {'value': 0.0, 'tooltip': 'Lat 0.25 Lon -26.75 V"

def test_generate_var_tstep_trace_leaflet_SCONC(FigureHandler):
    assert str(FigureHandler.generate_var_tstep_trace_leaflet(varname='SCONC_DUST', tstep=0))[0:200] == "GeoJSON(data={'type': 'FeatureCollection', 'features': [{'type': 'Feature', 'geometry': {'type': 'Point', 'coordinates': [-26.75, 0.25]}, 'properties': {'value': 0.009999999776482582, 'tooltip': 'Lat " \


def test_generate_var_tstep_trace_AOD(FigureHandler):
    assert FigureHandler.generate_var_tstep_trace(varname='OD550_DUST', tstep=0)['name'] == "MULTI-MODEL" 
    assert len(FigureHandler.generate_var_tstep_trace(varname='OD550_DUST', tstep=6)['lat']) == 22620


def test_generate_var_tstep_trace_SCONC(FigureHandler):
    assert FigureHandler.generate_var_tstep_trace(varname='SCONC_DUST', tstep=6)['name'] == "MULTI-MODEL" 
    assert len(FigureHandler.generate_var_tstep_trace(varname='SCONC_DUST', tstep=0)['lat']) == 22620


def test_get_title(FigureHandler):
    assert FigureHandler.get_title('OD550_DUST', tstep=0) == 'MULTI-MODEL Dust Optical Depth (550nm)<br>Valid: 12h 06 Jun 2022 (H+00)'
    assert FigureHandler.get_title('SCONC_DUST', tstep=9) == 'MULTI-MODEL Dust Surface Conc. (µg/m³)<br>Valid: 15h 07 Jun 2022 (H+27)'


def test_hour_to_step(FigureHandler):
    assert FigureHandler.hour_to_step(0) == 0
    assert FigureHandler.hour_to_step(1) == 0
    assert FigureHandler.hour_to_step(5) == 0
    assert FigureHandler.hour_to_step(36) == 8
    assert FigureHandler.hour_to_step(54) == 14
    assert FigureHandler.hour_to_step(70) == 0

def test_retrieve_var_tstep(FigureHandler):
    assert FigureHandler.retrieve_var_tstep(varname='OD550_DUST', tstep=0, hour=None, static=True, aspect=(1,1), center=None, selected_tiles='carto-positron', zoom=None, layer=None, tag='empty').children[0].id == {'tag': 'model-tile-layer', 'index': 'median'}
    assert FigureHandler.retrieve_var_tstep(varname='OD550_DUST', tstep=0, hour=None, static=True, aspect=(1,1), center=None, selected_tiles='carto-positron', zoom=None, layer=None, tag='empty').children[3].classes == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    assert str(FigureHandler.retrieve_var_tstep(varname='OD550_DUST', tstep=0, hour=None, static=True, aspect=(1,1), center=None, selected_tiles='carto-positron', zoom=None, layer=None, tag='empty').children[4].children) == "P(B(['MULTI-MODEL Dust Optical Depth (550nm)', Br(None), 'Valid: 12h 06 Jun 2022 (H+00)']))"

# =================== Scores Figure Handler ============================
@pytest.fixture
def ScoresFigureHandler():
    return code.ScoresFigureHandler('aeronet', 'bias', '202206')


def test_get_mapbox(ScoresFigureHandler):
    assert ScoresFigureHandler.get_mapbox('carto-positron', False, 2.8, None)['bearing'] == 0
    assert ScoresFigureHandler.get_mapbox('carto-positron', False, 2.8, None)['pitch'] == 0
    assert ScoresFigureHandler.get_mapbox('carto-positron', False, 2.8, None)['uirevision'] == True
    assert ScoresFigureHandler.get_mapbox('carto-positron', False, 2.8, None)['zoom'] == 2.8
    assert str(ScoresFigureHandler.get_mapbox('carto-positron', False, 2.8, None)['center']) == "layout.mapbox.Center({\n    'lat': 33.5, 'lon': 16.5\n})"


def test_generate_trace(ScoresFigureHandler):
    stats = ['Lille', 'Mainz', 'Palaiseau', 'Paris', 'Kyiv']
    vals = [-0.11, -0.12, -0.07, -0.09, -0.14]
    assert ScoresFigureHandler.generate_trace(35, 35, stats, vals)['name'] == 'MBE score'
    assert ScoresFigureHandler.generate_trace(35, 35, stats, vals)['marker']['cmin'] == -0.1
    assert ScoresFigureHandler.generate_trace(35, 35, stats, vals)['marker']['cmax'] == 0.1
    assert ScoresFigureHandler.generate_trace(35, 35, stats, vals)['marker']['colorbar']['x'] == 0.94

def test_retrieve_scores(ScoresFigureHandler):
    assert ScoresFigureHandler.retrieve_scores('median', aspect=(1,1), center=None).data[1].name == 'MBE score'  
    assert ScoresFigureHandler.retrieve_scores('median', aspect=(1,1), center=None).data[1].type == 'scattermapbox'  


# =================== Vis Handler ============================
@pytest.fixture
def VisFigureHandler():
    return code.VisFigureHandler('20220808')

def test_set_data(VisFigureHandler):
    assert VisFigureHandler.set_data(0)[5][1][0] == [11]
    assert VisFigureHandler.set_data(0)[5][3][0][1] == 1
    assert VisFigureHandler.set_data(24) == ([], [], [], [], [], ())
    assert VisFigureHandler.set_data(36) == ([], [], [], [], [], ())


def test_generate_var_tstep_trace(VisFigureHandler):
    returned = VisFigureHandler.generate_var_tstep_trace([], [], [], [], [], (), ('#714921', '#da7230', '#fcd775', 'CadetBlue'), ('<1 km', '1 - 2 km', '2 - 5 km', 'Haze'), ('o', 'o', 'o', '^'), 6)
    assert len(returned) == 2
    assert str(type(returned[0])) == "<class 'pandas.core.frame.DataFrame'>"
    assert returned[1][1].id == 'vis-info'
    assert returned[1][1].children ==['NO DATA AVAILABLE']
    assert returned[1][0].data['type'] == 'FeatureCollection'

def test_vis_get_title(VisFigureHandler):
    assert str(VisFigureHandler.get_title(tstep=0)) =="['Visibility reduced by airborne dust', Br(None), '08 August 2022 00-06 UTC']"
    assert str(VisFigureHandler.get_title(tstep=9)) =="['Visibility reduced by airborne dust', Br(None), '08 August 2022 09-15 UTC']"
    assert str(VisFigureHandler.get_title(tstep=39)) =="['Visibility reduced by airborne dust', Br(None), '08 August 2022 39-45 UTC']"
    assert str(VisFigureHandler.get_title(tstep=72)) =="['Visibility reduced by airborne dust', Br(None), '08 August 2022 72-78 UTC']"

def test_vis_retrieve_var_tstep(VisFigureHandler):
    result = VisFigureHandler.retrieve_var_tstep(tstep=0, hour=None, static=True, aspect=(1,1), center=None)
    assert str(type(result[0])) == "<class 'pandas.core.frame.DataFrame'>"
    assert result[1][0].data['type'] =='FeatureCollection'
    assert result[1][0].data['features'][0]['geometry']['coordinates'] ==[50.82, 28.97]

    result = VisFigureHandler.retrieve_var_tstep(tstep=1, hour=1, static=True, aspect=(1,1), center=None)
    assert str(type(result[0])) == "<class 'pandas.core.frame.DataFrame'>"
    assert result[1][0].data['type'] =='FeatureCollection'

# =================== Prob Handler ============================
@pytest.fixture
def ProbFigureHandler():
    return code.ProbFigureHandler('OD550_DUST', 0.1, '20220808')


def test_prob_set_data(ProbFigureHandler):
    assert ProbFigureHandler.set_data('OD550_DUST', tstep=0)[0].data[0] == -24.75
    assert ProbFigureHandler.set_data('OD550_DUST', tstep=0)[0].data[9] == -20.25
    assert ProbFigureHandler.set_data('OD550_DUST', tstep=0)[1].data[9] == 5.25


def test_prob_retrieve_cdatetime(ProbFigureHandler):
    assert str(ProbFigureHandler.retrieve_cdatetime(tstep=0)) == '2022-08-08 00:00:00'
    assert str(ProbFigureHandler.retrieve_cdatetime(tstep=1)) == '2022-08-09 00:00:00'

def test_prob_generate_contour_tstep_trace_AOD(ProbFigureHandler):
    #test day 0
    assert ProbFigureHandler.generate_contour_tstep_trace('OD550_DUST', tstep=0)[0].url == '/dashboard/assets/geojsons/prob/od550_dust/0.1/geojson/20220808/00_20220808_OD550_DUST.geojson'
    assert ProbFigureHandler.generate_contour_tstep_trace('OD550_DUST', tstep=0)[0].options == {'style': {'variable': 'forecastTab.forecastMaps.styleHandle'}}
    assert ProbFigureHandler.generate_contour_tstep_trace('OD550_DUST', tstep=0)[1].classes ==[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    #test day 1
    assert ProbFigureHandler.generate_contour_tstep_trace('OD550_DUST', tstep=1)[0].url == '/dashboard/assets/geojsons/prob/od550_dust/0.1/geojson/20220808/01_20220808_OD550_DUST.geojson'
    assert ProbFigureHandler.generate_contour_tstep_trace('OD550_DUST', tstep=1)[0].options == {'style': {'variable': 'forecastTab.forecastMaps.styleHandle'}}
    assert ProbFigureHandler.generate_contour_tstep_trace('OD550_DUST', tstep=1)[1].classes ==[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

def test_prob_generate_contour_tstep_trace_SCONC(ProbFigureHandler):
    #test day 0
    assert ProbFigureHandler.generate_contour_tstep_trace('SCONC_DUST', tstep=0)[0].url == '/dashboard/assets/geojsons/prob/od550_dust/0.1/geojson/20220808/00_20220808_OD550_DUST.geojson'
    assert ProbFigureHandler.generate_contour_tstep_trace('SCONC_DUST', tstep=0)[0].options == {'style': {'variable': 'forecastTab.forecastMaps.styleHandle'}}
    assert ProbFigureHandler.generate_contour_tstep_trace('SCONC_DUST', tstep=0)[1].classes ==[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    #test day 1
    assert ProbFigureHandler.generate_contour_tstep_trace('SCONC_DUST', tstep=1)[0].url == '/dashboard/assets/geojsons/prob/od550_dust/0.1/geojson/20220808/01_20220808_OD550_DUST.geojson'
    assert ProbFigureHandler.generate_contour_tstep_trace('SCONC_DUST', tstep=1)[0].options == {'style': {'variable': 'forecastTab.forecastMaps.styleHandle'}}
    assert ProbFigureHandler.generate_contour_tstep_trace('SCONC_DUST', tstep=1)[1].classes ==[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

def test_prob_get_title(ProbFigureHandler):
    assert ProbFigureHandler.get_title('OD550_DUST', tstep=0) =='Daily Mean of Dust AOD<br>Probability of exceeding 0.1<br>ENS members: 10 Run: 08 Aug 2022 Valid: 08 Aug 2022'
    assert ProbFigureHandler.get_title('SCONC_DUST', tstep=1) == 'Daily Mean of Dust Surface Concentration<br>Probability of exceeding 0.1µg/m³<br>ENS members: 10 Run: 08 Aug 2022 Valid: 09 Aug 2022'

def test_prob_retrieve_var_tstep(ProbFigureHandler):
    assert ProbFigureHandler.retrieve_var_tstep('OD550_DUST', 0, True, (1,1))[0].url =='/dashboard/assets/geojsons/prob/od550_dust/0.1/geojson/20220808/00_20220808_OD550_DUST.geojson'
    assert ProbFigureHandler.retrieve_var_tstep('OD550_DUST', 1, True, (1,1))[0].options =={'style': {'variable': 'forecastTab.forecastMaps.styleHandle'}}

    assert ProbFigureHandler.retrieve_var_tstep('SCONC_DUST', 1, True, (1,1))[0].url =='/dashboard/assets/geojsons/prob/od550_dust/0.1/geojson/20220808/01_20220808_OD550_DUST.geojson'
    assert ProbFigureHandler.retrieve_var_tstep('SCONC_DUST', 0, True, (1,1))[0].options =={'style': {'variable': 'forecastTab.forecastMaps.styleHandle'}}


# =================== Was Handler ============================
@pytest.fixture
def WasFigureHandler():
    return code.WasFigureHandler(was='burkinafaso', model='median', variable='SCONC_DUST', selected_date='20220808')

def test_was_get_regions_data(WasFigureHandler):
    #day 1
    assert WasFigureHandler.get_regions_data(day=1)[0][0] == 'Boucle du Mouhoun'
    assert WasFigureHandler.get_regions_data(day=1)[0][1] == 'Cascades'
    assert WasFigureHandler.get_regions_data(day=1)[0][-1] == 'Sud-Ouest'

    assert WasFigureHandler.get_regions_data(day=1)[1][0] == 'green'
    assert WasFigureHandler.get_regions_data(day=1)[1][1] == 'green'
    assert WasFigureHandler.get_regions_data(day=1)[1][-1] == 'green'

    assert WasFigureHandler.get_regions_data(day=1)[2][0] == 'Normal'
    assert WasFigureHandler.get_regions_data(day=1)[2][1] == 'Normal'
    assert WasFigureHandler.get_regions_data(day=1)[2][-1] =='Normal'

    #day 2
    assert WasFigureHandler.get_regions_data(day=2)[0][0] == 'Boucle du Mouhoun'
    assert WasFigureHandler.get_regions_data(day=2)[0][1] == 'Cascades'
    assert WasFigureHandler.get_regions_data(day=2)[0][-1] == 'Sud-Ouest'

    assert WasFigureHandler.get_regions_data(day=2)[1][0] == 'green'
    assert WasFigureHandler.get_regions_data(day=2)[1][1] == 'green'
    assert WasFigureHandler.get_regions_data(day=2)[1][-1] == 'green'

    assert WasFigureHandler.get_regions_data(day=2)[2][0] == 'Normal'
    assert WasFigureHandler.get_regions_data(day=2)[2][1] == 'Normal'
    assert WasFigureHandler.get_regions_data(day=2)[2][-1] =='Normal'

    
def test_was_get_geojson_url(WasFigureHandler):
    assert WasFigureHandler.get_geojson_url(day=1) == '/dashboard/assets/geojsons/was/burkinafaso/geojson/20220808/20220808_SCONC_DUST_1.geojson'
    assert WasFigureHandler.get_geojson_url(day=2) == '/dashboard/assets/geojsons/was/burkinafaso/geojson/20220808/20220808_SCONC_DUST_2.geojson'
    
def test_was_retrieve_cdatetime(WasFigureHandler):
    assert str(WasFigureHandler.retrieve_cdatetime(tstep=0)) == '2022-08-08 12:00:00'
    assert str(WasFigureHandler.retrieve_cdatetime(tstep=1)) == '2022-08-08 15:00:00'
    assert str(WasFigureHandler.retrieve_cdatetime(tstep=2)) == '2022-08-08 18:00:00'
    assert str(WasFigureHandler.retrieve_cdatetime(tstep=3)) == '2022-08-08 21:00:00'


def test_was_generate_contour_tstep_trace(WasFigureHandler):
    assert WasFigureHandler.generate_contour_tstep_trace(1)[0].options == {'style': {'variable': 'forecastTab.wasMaps.styleHandle'}}
    assert WasFigureHandler.generate_contour_tstep_trace(1)[0].url == '/dashboard/assets/geojsons/was/burkinafaso/geojson/20220808/20220808_SCONC_DUST_1.geojson'
    assert WasFigureHandler.generate_contour_tstep_trace(1)[1].className == 'was-legend'

    assert WasFigureHandler.generate_contour_tstep_trace(2)[0].options == {'style': {'variable': 'forecastTab.wasMaps.styleHandle'}}
    assert WasFigureHandler.generate_contour_tstep_trace(2)[0].url == '/dashboard/assets/geojsons/was/burkinafaso/geojson/20220808/20220808_SCONC_DUST_2.geojson'
    assert WasFigureHandler.generate_contour_tstep_trace(2)[1].className == 'was-legend'

    
def test_was_get_title(WasFigureHandler):
    assert str(WasFigureHandler.get_title(0)) =="Barcelona Dust Regional Center - Burkina Faso WAS.<br>Expected concentration of airborne dust.<br>Issued: 08 Aug 2022. Valid: 08 Aug 2022"
    assert str(WasFigureHandler.get_title(1)) =="Barcelona Dust Regional Center - Burkina Faso WAS.<br>Expected concentration of airborne dust.<br>Issued: 08 Aug 2022. Valid: 09 Aug 2022"


def test_was_retrieve_var_tstep(WasFigureHandler):
    assert WasFigureHandler.retrieve_var_tstep(1, True, (1,1))[0].url =='/dashboard/assets/geojsons/was/burkinafaso/geojson/20220808/20220808_SCONC_DUST_1.geojson'
    assert WasFigureHandler.retrieve_var_tstep(1, True, (1,1))[0].options =={'style': {'variable': 'forecastTab.wasMaps.styleHandle'}}

    assert WasFigureHandler.retrieve_var_tstep(2, True, (1,1))[0].url =='/dashboard/assets/geojsons/was/burkinafaso/geojson/20220808/20220808_SCONC_DUST_2.geojson'
    assert WasFigureHandler.retrieve_var_tstep(2, True, (1,1))[0].options =={'style': {'variable': 'forecastTab.wasMaps.styleHandle'}}

