import pytest
import pandas as pd
import importlib
import numpy as np
from contextvars import copy_context
import dash
from dash._callback_context import context_value
from dash._utils import AttributeDict
code = importlib.import_module('tabs.evaluation_callbacks')

#add equality checker for objects
def __eq__(self, other):
    if isinstance(self, other.__class__):
        return self.a == other.a and self.b == other.b
    return False

#============ TEST extend_l============================================
def test_extend_l():
    assert code.extend_l([[1],[2],[3]]) == [1,2,3]

#============ TEST render_evaluation_tab=================================
def test_render_evaluation_tab():
    def run_callback():
        context_value.set(AttributeDict(**{"triggered_inputs": [{"prop_id": "nrt-evaluation.n_clicks"},{"prop_id": "scores-evaluation.n_clicks"}]}))
        return code.render_evaluation_tab(0, 0) 

    ctx = copy_context()
    output = ctx.run(run_callback)
    assert output[0] == dash.no_update
    assert output[1:] == ({ 'fontWeight': 'bold' }, { 'fontWeight': 'normal' })


#============ TEST _no_data_modis========================================
def test_no_data_modis():
    assert code._no_modis_data() == ([{'name': 'NO DATA', 'id': ''}], [], {'display': 'block'})

#============ TEST update_time_selection===================================
def test_update_time_selection():
    def run_callback():
        context_value.set(AttributeDict(**{"triggered_inputs": [{"prop_id": "obs-timescale-dropdown.value"},{"prop_id": "obs-network-dropdown.value"}]}))
        return code.update_time_selection('seasonal', 'modis') 

    ctx = copy_context()
    output = ctx.run(run_callback)
    assert "'Spring 2018', 'value': '201803-201805'}], 'Select season')" in str(output)


#============ TEST modis_scores_tables_retrieve========================
def test_modis_scores_tables_retrieve_no_n_click():
    def run_callback():
        context_value.set(AttributeDict(**{"triggered_inputs": 
            [{"prop_id": "scores-apply.n_clicks"},
                {"prop_id": "obs-models-dropdown.value"},
                {"prop_id": "obs-statistics-dropdown.value"},
                {"prop_id": "obs-network-dropdown.value"},
                {"prop_id": "obs-timescale-dropdown.value"},
                {"prop_id": "obs-selection-dropdown.value"}]}))
        return code.modis_scores_tables_retrieve(0, ['median'],['bias'],'modis','monthly','202208' ) 

    ctx = copy_context()
    output = ctx.run(run_callback)
    assert output[0] == dash.no_update
    assert output[1] == dash.no_update
    assert output[2] == {'display':'none'}

def test_modis_scores_tables_retrieve_median_202206():
    def run_callback():
        context_value.set(AttributeDict(**{"triggered_inputs": 
            [{"prop_id": "scores-apply.n_clicks"},
                {"prop_id": "obs-models-dropdown.value"},
                {"prop_id": "obs-statistics-dropdown.value"},
                {"prop_id": "obs-network-dropdown.value"},
                {"prop_id": "obs-timescale-dropdown.value"},
                {"prop_id": "obs-selection-dropdown.value"}]}))
        return code.modis_scores_tables_retrieve(1, ['median'],['bias'],'modis','monthly','202206' ) 

    ctx = copy_context()
    output = ctx.run(run_callback)
    assert output == ([{'id': 'model', 'name': ''}, {'id': 'bias', 'name': 'MBE'}], [{'bias': '-0.09', 'model': 'MULTI-MODEL'}], {'display': 'block'}) 

def test_modis_scores_tables_retrieve_no_data():
    def run_callback():
        context_value.set(AttributeDict(**{"triggered_inputs": 
            [{"prop_id": "scores-apply.n_clicks"},
                {"prop_id": "obs-models-dropdown.value"},
                {"prop_id": "obs-statistics-dropdown.value"},
                {"prop_id": "obs-network-dropdown.value"},
                {"prop_id": "obs-timescale-dropdown.value"},
                {"prop_id": "obs-selection-dropdown.value"}]}))
        return code.modis_scores_tables_retrieve(1, ['median'],['bias'],'modis','monthly','212208' ) 

    ctx = copy_context()
    output = ctx.run(run_callback)
    assert output == ([{'id': '', 'name': 'NO DATA'}], [], {'display': 'block'})


#============ TEST aeronet_scores_tables_retrieve========================
def test_aeronet_scores_tables_retrieve_no_n_click():
    def run_callback():
        context_value.set(AttributeDict(**{"triggered_inputs": 
            [{"prop_id": "scores-apply.n_clicks"},
                {"prop_id": "obs-models-dropdown.value"},
                {"prop_id": "obs-statistics-dropdown.value"},
                {"prop_id": "obs-network-dropdown.value"},
                {"prop_id": "obs-timescale-dropdown.value"},
                {"prop_id": "obs-selection-dropdown.value"}]}))
        return code.aeronet_scores_tables_retrieve(0, None, None, None, None, None, ['median'], ['bias'], 'aeronet', 'monthly', '202208', [], [], None, [], [], None, [], [], None, [], [], None,[], [], None)  
    ctx = copy_context()
    output = ctx.run(run_callback)
    assert output[0] == dash.no_update
    assert output[1] == dash.no_update
    assert output[2] == {'display':'none'}

def test_aeronet_scores_tables_retrieve_median_202206():
    def run_callback():
        context_value.set(AttributeDict(**{"triggered_inputs": 
            [{"prop_id": "scores-apply.n_clicks"},
                {"prop_id": "obs-models-dropdown.value"},
                {"prop_id": "obs-statistics-dropdown.value"},
                {"prop_id": "obs-network-dropdown.value"},
                {"prop_id": "obs-timescale-dropdown.value"},
                {"prop_id": "obs-selection-dropdown.value"}]}))
        return code.aeronet_scores_tables_retrieve(1, None, None, None, None, None, ['median'], ['bias'], 'aeronet', 'monthly', '202208', [], [], None, [], [], None, [], [], None, [], [], None,[], [], None)  
    ctx = copy_context()
    output = ctx.run(run_callback)
    assert output[0] == [{'id': 'station', 'name': ['MBE', '']}, {'id': 'median', 'name': ['MBE', 'MULTI-MODEL']}]
    assert output[1] == [{'median': '-0.17', 'station': 'Europe'}, {'median': '-0.11', 'station': 'Mediterranean'}, {'median': '-0.31', 'station': 'MiddleEast'}, {'median': '-0.03', 'station': 'NAfrica'}, {'median': '-0.11', 'station': 'Total'}]
 

def test_aeronet_scores_tables_retrieve_no_data():
    def run_callback():
        context_value.set(AttributeDict(**{"triggered_inputs": 
            [{"prop_id": "scores-apply.n_clicks"},
                {"prop_id": "obs-models-dropdown.value"},
                {"prop_id": "obs-statistics-dropdown.value"},
                {"prop_id": "obs-network-dropdown.value"},
                {"prop_id": "obs-timescale-dropdown.value"},
                {"prop_id": "obs-selection-dropdown.value"}]}))
        return code.aeronet_scores_tables_retrieve(1, None, None, None, None, None, ['median'], ['bias'], 'aeronet', 'monthly', '212208', [], [], None, [], [], None, [], [], None, [], [], None,[], [], None)  

    ctx = copy_context()
    output = ctx.run(run_callback)
    assert output[0] == [{'id': 'station', 'name': ['NO DATA']},{'id': 'station', 'name': ['NO DATA']}, {'id': 'station', 'name': ['NO DATA']},  {'id': 'station', 'name': ['NO DATA']}, {'id': 'station', 'name': ['NO DATA']}]
