"""
    data fetching utils, function maps, and constant variables
    collection of objects
"""

from datetime import datetime, timedelta

#import kadlu.geospatial.data_sources.chs as chs
import kadlu.geospatial.data_sources.era5 as era5
import kadlu.geospatial.data_sources.gebco as gebco
import kadlu.geospatial.data_sources.hycom as hycom
import kadlu.geospatial.data_sources.wwiii as wwiii
#import kadlu.geospatial.data_sources.nemo as nemo


# dict for mapping strings to callback functions
load_map = dict(
#        bathy_chs           = chs  .Chs()  .load_bathymetry,
        #temp_hycom          = hycom.Hycom().load_temp,
        temperature_hycom   = hycom.Hycom().load_temp,
        salinity_hycom      = hycom.Hycom().load_salinity,
        water_uv_hycom      = hycom.Hycom().load_water_uv,
        water_u_hycom       = hycom.Hycom().load_water_u,
        water_v_hycom       = hycom.Hycom().load_water_v,
        wavedir_era5        = era5 .Era5() .load_wavedirection,
        wavedirection_era5  = era5 .Era5() .load_wavedirection,
        waveheight_era5     = era5 .Era5() .load_windwaveswellheight,
        waveperiod_era5     = era5 .Era5() .load_waveperiod,
        wind_uv_era5        = era5 .Era5() .load_wind_uv,
        wind_u_era5         = era5 .Era5() .load_wind_u,
        wind_v_era5         = era5 .Era5() .load_wind_v,
        precipitation_era5  = era5 .Era5() .load_precipitation,
        snowfall_era5       = era5 .Era5() .load_snowfall,
        flux_ocean_era5     = era5 .Era5() .load_flux_ocean,
        flux_waves_era5     = era5 .Era5() .load_flux_waves,
        stress_ocean_era5   = era5 .Era5() .load_stress_ocean,
        #precip_type_era5    = era5 .Era5() .load_precip_type,
        wavedir_wwiii       = wwiii.Wwiii().load_wavedirection,
        wavedirection_wwiii = wwiii.Wwiii().load_wavedirection,
        waveheight_wwiii    = wwiii.Wwiii().load_windwaveheight,
        waveperiod_wwiii    = wwiii.Wwiii().load_waveperiod,
        wind_uv_wwiii       = wwiii.Wwiii().load_wind_uv,
        wind_u_wwiii        = wwiii.Wwiii().load_wind_u,
        wind_v_wwiii        = wwiii.Wwiii().load_wind_v,
        #bathy_gebco         = gebco.Gebco().load_bathymetry,
        bathymetry_gebco    = gebco.Gebco().load_bathymetry,
        #water_u_nemo        = nemo .Nemo().load_uvelocity,
        #water_v_nemo        = nemo .Nemo().load_vvelocity,
        #water_w_nemo        = nemo .Nemo().load_wvelocity,
        #salinity_nemo       = nemo .Nemo().load_salinity,
        #temp_nemo           = nemo .Nemo().load_temperature,
        #turbidity_nemo      = nemo .Nemo().load_fraserturbidity,
    )

precip_type_era5_map = {
        0   :   'Reserved',
        1   :   'Rain',
        2   :   'Thunderstorm',
        3   :   'Freezing rain',
        4   :   'Mixed/Ice',
        5   :   'Snow',
        6   :   'Wet snow',
        7   :   'Mixture of rain and snow',
        8   :   'Ice pellets',
        9   :   'Graupel',
        10  :   'Hail',
        11  :   'Drizzle',
        12  :   'Freezing drizzle',
        255 :   'Missing',
    }
_ = [precip_type_era5_map.update({i : 'Reserved'}) for i in range(13, 192)]
_ = [precip_type_era5_map.update({i : 'Reserved for local use'}) for i in range(192, 255)]

precip_type_map = dict(
    era5 = (era5.Era5().load_precip_type, precip_type_era5_map)
)

default_val = dict(
        south=44.25, west=-64.5,
        north=44.70, east=-63.33,
        top=0, bottom=5000,
        start=datetime(2015, 3, 1), end=datetime(2015, 3, 1, 12)
    )

var3d = ('temp', 'temperature', 'salinity', 'water_u', 'water_v', 'water_uv',)

source_map = (
    """
    CHS   (Canadian Hydrography Service)
          bathymetry:       bathymetric data in Canada's waterways. metres, variable resolution \n
    ERA5  (Global environmental dataset from Copernicus Climate Data Store)
          wavedir:          mean wave direction, degrees
          waveheight:       combined height of wind, waves, and swell. metres
          waveperiod:       mean wave period, seconds
          wind_uv:          wind speed computed as sqrt(u^2 + v^2) / 2, where u, v are direction vectors
          wind_u:           wind speed coordinate U-vector, m/s
          wind_v:           wind speed coordinate V-vector, m/s
          precipitation:
          precip_type:
          snowfall:
          flux_ocean:
          flux_waves:
          stress_ocean: \n
    GEBCO (General Bathymetric Chart of the Oceans)
          bathymetry:       global bathymetric and topographic data. metres below sea level \n
    HYCOM (Hybrid Coordinate Ocean Model)
          salinity:         g/kg salt in water
          temp:             degrees celsius
          water_uv:         ocean current computed as sqrt(u^2 + v^2) / 2, where u, v are direction vectors
          water_u:          ocean current coordinate U-vector, m/s
          water_v:          ocean current coordinate V-vector, m/s \n
    WWIII (WaveWatch Ocean Model Gen 3)
          wavedir:          primary wave direction, degrees
          waveheight:       combined height of wind and waves, metres
          waveperiod:       primary mean wave period, seconds
          wind_uv:          wind speed computed as sqrt(u^2 + v^2) / 2, where u, v are direction vectors
          wind_u:           wind speed coordinate U-vector, m/s
          wind_v:           wind speed coordinate V-vector, m/s \n
    NEMO  (3D zonal component fields from the SalishSeaCoast Model)
          water_u:
          water_v:
          water_w:
          salinity:
          temp:
          turbidity:
          mesozooplankton:
          microzooplankton:

    """)


class SourceMap():
    def fetch_map(self): return fetch_map 
    def load_map(self): return load_map
    def default_val(self): return default_val
    def var3d(self): return var3d
    def source_map(self): return source_map 

