#!/usr/bin/env python

# This file is part of chelsa_isimip3b_ba_1km.
#
# chelsa_isimip3b_ba_1km is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# chelsa_isimip3b_ba_1km is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with chelsa_isimip3b_ba_1km.  If not, see <https://www.gnu.org/licenses/>.

import os
from PySAGA import saga_api
from . import chelsa_functions
from . import saga_functions


def chelsa(coarse_data, dem_data, aux_data, srad_data, TEMP):
    # This function is to core of chelsa and calcuates
    # all variables. The functions for the variables
    # are defined in the chelsa_functions.py file

    # calculate wind effect
    print('  %CHELSA:      calculating wind effect')
    windef1 = chelsa_functions.calculate_windeffect(Coarse=coarse_data, Dem=dem_data)

    # correcting wind effect
    print('  %CHELSA:      correcting wind effect')
    wind_cor, wind_coarse25, windcoarse = chelsa_functions.correct_windeffect(windef1=windef1,
                                                                              Coarse=coarse_data,
                                                                              Dem=dem_data,
                                                                              Aux=aux_data)
    # save and clean up memory
    wind_cor.Save(os.path.join(TEMP, 'wind_cor.sgrd'))
    windcoarse.Save(os.path.join(TEMP, 'wincoarse.sgrd'))
    wind_coarse25.Save(os.path.join(TEMP, 'wind_coarse25.sgrd'))
    saga_api.SG_Get_Data_Manager().Delete()  # with SAGA 9.3.0 Delete_All() is replaced by Delete()

    wind_cor = saga_functions.load_sagadata(os.path.join(TEMP, 'wind_cor.sgrd'))
    windcoarse = saga_functions.load_sagadata(os.path.join(TEMP, 'wincoarse.sgrd'))
    wind_coarse25 = saga_functions.load_sagadata(os.path.join(TEMP, 'wind_coarse25.sgrd'))

    # downscale precipitation
    print('  %CHELSA:      downscale daily precipitation rate (pr)')
    pr = chelsa_functions.precipitation(wind_cor=wind_cor,
                                        wind_coarse=windcoarse,
                                        wind_coarse25=wind_coarse25,
                                        Coarse=coarse_data,
                                        Aux=aux_data)

    # save and clean up memory
    pr.Save(os.path.join(TEMP, 'pr.sgrd'))
    saga_api.SG_Get_Data_Manager().Delete()  # with SAGA 9.3.0 Delete_All() is replaced by Delete()

    # downscale cloud cover
    print('  %CHELSA:      downscale cloud cover (only needed for radiation correction)')
    # reload wind_cor, otherwise we will get a segmentation fault, because
    # SWIG/SAGA
    wind_cor = saga_functions.load_sagadata(os.path.join(TEMP, 'wind_cor.sgrd'))
    cc_fin = chelsa_functions.cloudcover(Coarse=coarse_data,
                                         wind_cor=wind_cor)

    # downscale cloud cover
    print('  %CHELSA:      downscale surface downward solar radiation (rsds)')
    rsds = chelsa_functions.solar_radiation(Srad=srad_data,
                                            Coarse=coarse_data,
                                            cc_fin=cc_fin)

    # save and clean up memory
    rsds.Save(os.path.join(TEMP, 'rsds.sgrd'))
    saga_api.SG_Get_Data_Manager().Delete()  # with SAGA 9.3.0 Delete_All() is replaced by Delete()

    # downscale tas
    print('  %CHELSA:      downscale daily average temperature (tas)')
    tas = chelsa_functions.temperature(Coarse=coarse_data,
                                       Dem=dem_data,
                                       Aux=aux_data,
                                       var='tas')

    # save and clean up memory
    tas.Save(os.path.join(TEMP, 'tas.sgrd'))
    saga_api.SG_Get_Data_Manager().Delete()  # with SAGA 9.3.0 Delete_All() is replaced by Delete()

    # downscale tasmin
    print('  %CHELSA:      downscale daily minimum temperature (tasmin)')
    tasmin = chelsa_functions.temperature(Coarse=coarse_data,
                                          Dem=dem_data,
                                          Aux=aux_data,
                                          var='tasmin')

    # downscale tasmax
    print('  %CHELSA:      downscale daily maximum temperature (tasmax)')
    tasmax = chelsa_functions.temperature(Coarse=coarse_data,
                                          Dem=dem_data,
                                          Aux=aux_data,
                                          var='tasmax')

    # avoid delta tasmax tasmin being negative due to interpolation artefacts
    tasmax = saga_functions.grid_statistics(tasmax,
                                            tasmin, 0).asGrid()

    tasmin = saga_functions.grid_statistics(tasmax,
                                            tasmin, 1).asGrid()

    # load rsds, pr and tas again
    rsds = saga_functions.load_sagadata(os.path.join(TEMP, 'rsds.sgrd'))
    pr = saga_functions.load_sagadata(os.path.join(TEMP, 'pr.sgrd'))
    tas = saga_functions.load_sagadata(os.path.join(TEMP, 'tas.sgrd'))

    return tas, tasmax, tasmin, rsds, pr


