'''
    emissionDataset - This library help to create required dataset for the pre-processing
'''
import numpy as np
import sys, os
from datetime import datetime
import pandas as pd
from emissionglobals import appGlobal
from emissionspatial import geoLocation
import json

class emissionTimeseries(appGlobal):
    """
        This class provide timeseries information of data provided as input
    """
    def __init__(self, objConfig, rasterType):
        self.config = objConfig.getConfig()
        self.rasterType = rasterType

    def getTimeseriesDataFrame(self):
        """
            This method read input rasters names, analyze it and return the given timeseries
            as dataframe
        """
        try:            
            df_list = []

            for cElements in self.config:
                if self.config[cElements]["type"] == self.rasterType:                   
                    rasterPath = self.config[cElements]["data_Path"]
                    datasetName = cElements
                    file_format = self.config[cElements]["file_format"]
                    filename_Start_at = self.config[cElements]["filename_Start_at"]
                    filename_End_at = self.config[cElements]["filename_End_at"]

                    raster_df = pd.DataFrame(columns=['dataset','fileName','datetime'])                    
                    raster_df['fileName'] = [f for f in os.listdir(rasterPath) if f.endswith('.tif')] #os.listdir(rasterPath)
                    raster_df['dataset'] = datasetName
                    
                    if(not filename_Start_at == -1 and not filename_End_at == -1):
                        raster_df['datetime'] = [datetime.strptime(g[filename_Start_at:filename_End_at], file_format) for g in raster_df['fileName']]

                    elif(not filename_Start_at == -1 and filename_End_at == -1):
                        raster_df['datetime'] = [datetime.strptime(g[filename_Start_at:], file_format) for g in raster_df['fileName']]

                    elif(filename_Start_at == -1 and not filename_End_at == -1):
                        raster_df['datetime'] = [datetime.strptime(g[:filename_End_at], file_format) for g in raster_df['fileName']]
                    else:
                        raster_df['datetime'] = [datetime.strptime(g, file_format) for g in raster_df['fileName']]
                    
                    raster_df["date"] = raster_df["datetime"].apply(lambda x:x.strftime('%m-%d-%Y'))
                    raster_df["month"] = raster_df["datetime"].apply(lambda x:x.strftime('%B-%Y')) 
                    raster_df["year"] = raster_df["datetime"].apply(lambda x:x.strftime('%Y'))

                    df_list.append(raster_df)

            all_timeSeries_df = pd.concat(df_list)
            
            return all_timeSeries_df            

        except Exception as e:
            print(e)
            print("Failed at emissiondataset.py - getTimeseriesDataFrame")
            raise

class generatorDataset():
    """
        Provide data that has been generated by Power Plants
    """
    def __init__(self, appGlobal, type):
        self.appGlobal = appGlobal
        self.objAppConfig = appGlobal.objAppConfig
        self.generatorObj = self.objAppConfig.getGenerationConfigObj(type)

    def getEGeneratorAsGeoDataFrame(self):
        """
            Convert GPPD shape csv file to Geopandas dataframe
        """
        try:
            requiredColumns = []
            for key in self.generatorObj["required_columns"]:
                requiredColumns.append(self.generatorObj["required_columns"][key])
            
            #requiredColumns.append("fuelcons")

            gl = geoLocation(self.generatorObj, requiredColumns)

            gpDF = gl.getGeoLocationAsDataframe()

            gpDF = self.fix_estimated_generation(gpDF)            

            return gpDF, self.generatorObj["required_columns"]
        except Exception as e:
            print(e)
            print("Failed at emissiondataset.py - getEGeneratorAsGeoDataFrame")
            raise
        

    def fix_estimated_generation(self, gpp_df): 
        """
            Update capcity factor of power plant.
            correct and update estimated capacity in gwh, if capacity factor is greater than 1
        """
        try:
            source_capacity_factors = self.generatorObj["source_capacity_factors"]
            capacity_in_mw = self.generatorObj["required_columns"]["capacity_in_mw"]
            estimated_capacity_in_gwh = self.generatorObj["required_columns"]["estimated_capacity_in_gwh"]
            fuel_type = self.generatorObj["required_columns"]["fuel_type"]

            gpp_df["capacity_factor"] = np.where(gpp_df[capacity_in_mw] > 0, 
                        gpp_df[estimated_capacity_in_gwh] / (gpp_df[capacity_in_mw]*24*365/1000), 0)

            for idx in range(gpp_df.shape[0]):
                if gpp_df.loc[idx, 'capacity_factor'] > 1: 
                    gpp_df.loc[idx, 'capacity_factor'] = source_capacity_factors[gpp_df.loc[idx, fuel_type]]
                    gpp_df.loc[idx, estimated_capacity_in_gwh] = gpp_df.loc[idx, "capacity_factor"] * gpp_df.loc[idx, capacity_in_mw] * 24*365/1000
            return gpp_df
            
        except Exception as e:
            print(e)
            print("Failed at emissiondataset.py - fix_estimated_generation")
            raise

    def getRequiredColumns(self):
        return self.generatorObj["required_columns"]