<reponame>gitter-badger/Hypatia
# -*- coding: utf-8 -*-
"""
This module contains a series of functions for checking the
possible mistakes in the input data to raise
the apporpriate error and inform the user.
"""

import pandas as pd

from hypatia.error_log.Exceptions import (
    WrongIndex,
    NanValues,
    WrongTableName,
    WrongSheetName,
    WrongMappingData,
    WrongMappingTech,
    WrongTechCategory,
    WrongCarrierType,
    WrongNumberOfYears,
)


def check_index(index, table_name, file_name, allowed_indices):
    """Checks if the columns in the set files have valid names
    """

    if not index.equals(allowed_indices):

        raise WrongIndex(
            f"The index/column {list(index)} in the 'table_name' table of '{file_name}' file includes invalid names\
                                       or misses an index/column.Valid index/column names are {list(allowed_indices)}"
        )


def check_index_data(index, sheet_name, file_name, allowed_indices):
    """Checks if the indices and columns in the parameter files have valid names
    """

    if not index.equals(allowed_indices):
        print(index, allowed_indices)
        raise WrongIndex(
            f"The index/column {list(index)} in the '{sheet_name}' sheet of '{file_name}' file includes invalid names\
                                       or misses an index/column.Valid index/column names are {list(allowed_indices)}"
        )


def check_nan(table_name, table_value, file_name):
    """Checks if there are nan values in the set and parameter tables and sheets
    """

    if table_value.isnull().values.any():

        raise NanValues(
            f"There are Nan values in '{table_name}' table in the '{file_name}' file.\
                        Check for missing or extra rows and columns"
        )


def check_table_name(
    file_name, allowed_names, table_name,
):

    """Checks if the tables in the set files have valid names
    """

    if table_name not in allowed_names:

        raise WrongTableName(
            f"The table name '{table_name}' in the '{file_name}' file is not a valid name.\
                               valid table names are {allowed_names}"
        )


def check_sheet_name(path, file_name, ids):

    """Checks if the sheets in the parameter files have valid names when 
    reading the data
    """

    file = pd.ExcelFile(r"{}/{}.xlsx".format(path, file_name))
    sheet_list = file.sheet_names
    allowed_list = []

    for key, value in ids.items():

        allowed_list.append(value["sheet_name"])

    for sheet in sheet_list:

        if sheet not in allowed_list:

            raise WrongSheetName(
                f"The sheet name '{sheet}' in the '{file_name}' file is not a valid name.\
                               valid sheet names are '{allowed_list}'"
            )


def check_tech_category(tech_table, allowed_categories, file_name):

    """Checks if the given technology categories are within the acceptable
    tech categories of the model
    """

    for tech_ctgry in tech_table["Tech_category"]:

        if tech_ctgry not in allowed_categories:

            raise WrongTechCategory(
                f"'{tech_ctgry}' category in Technologies table\
                                    in '{file_name}' file is not a valid technology category.\
                                        Valied categories are {allowed_categories}"
            )


def check_carrier_type(carr_table, allowed_types, file_name):

    """Checks if the given carrier types are within the acceptable
    carrier types of the model
    """

    for carr_type in carr_table["Carr_type"]:

        if carr_type not in allowed_types:

            raise WrongCarrierType(
                f"'{carr_type}' type in Carriers table in '{file_name}' file is not a valid carrier type. Valied types are {allowed_types}"
            )


def check_mapping_values(
    mapping_table,
    mapping_name,
    reference_table,
    reference_name,
    mapping_col,
    reference_col,
    file_name,
):

    """Checks if the specified carriers and technologies in the carrier input
    and carrier output tables have valid names
    """

    if not set(mapping_table[mapping_col]).issubset(
        set(reference_table[reference_col])
    ):

        raise WrongMappingData(
            f"There is an invalid name in '{mapping_col}' column of '{mapping_name}' table, in the '{file_name}'\
                               set file. Check the consistency between '{mapping_name}' table and '{reference_name}' table"
        )


def check_mapping_ctgry(
    mapping_table, table_name, technologies_table, tech_ctgry, file_name
):

    """Checks if there are valid technology categories in the carrier input and
    carrier output tables
    """
    for tech in mapping_table["Technology"]:

        if (
            technologies_table.loc[technologies_table["Technology"] == tech][
                "Tech_category"
            ].item()
            == tech_ctgry
        ):

            raise WrongMappingTech(
                f"Technologies with '{tech_ctgry}' category cannot be included in '{table_name}' table.\
                                   Modify '{table_name}' table in the '{file_name}' set file."
            )


def check_years_mode_consistency(mode, main_years):

    """Checks if the number of years is valid based on the given optimization
    mode
    """

    if mode == "Operation":

        if len(main_years) != 1:

            raise WrongNumberOfYears(
                f"The number of years is invalid.The '{mode}' optimization mode of the energy system\
                                     can be analyzed only with 'one year' time horizon"
            )

# -*- coding: utf-8 -*-
"""
This module contains a series of functions for checking the
possible mistakes in the input data to raise
the apporpriate error and inform the user.
"""

import pandas as pd

from hypatia.error_log.Exceptions import (
    WrongIndex,
    NanValues,
    WrongTableName,
    WrongSheetName,
    WrongMappingData,
    WrongMappingTech,
    WrongTechCategory,
    WrongCarrierType,
    WrongNumberOfYears,
)


def check_index(index, table_name, file_name, allowed_indices):
    """Checks if the columns in the set files have valid names
    """

    if not index.equals(allowed_indices):

        raise WrongIndex(
            f"The index/column {list(index)} in the 'table_name' table of '{file_name}' file includes invalid names\
                                       or misses an index/column.Valid index/column names are {list(allowed_indices)}"
        )


def check_index_data(index, sheet_name, file_name, allowed_indices):
    """Checks if the indices and columns in the parameter files have valid names
    """

    if not index.equals(allowed_indices):
        print(index, allowed_indices)
        raise WrongIndex(
            f"The index/column {list(index)} in the '{sheet_name}' sheet of '{file_name}' file includes invalid names\
                                       or misses an index/column.Valid index/column names are {list(allowed_indices)}"
        )


def check_nan(table_name, table_value, file_name):
    """Checks if there are nan values in the set and parameter tables and sheets
    """

    if table_value.isnull().values.any():

        raise NanValues(
            f"There are Nan values in '{table_name}' table in the '{file_name}' file.\
                        Check for missing or extra rows and columns"
        )


def check_table_name(
    file_name, allowed_names, table_name,
):

    """Checks if the tables in the set files have valid names
    """

    if table_name not in allowed_names:

        raise WrongTableName(
            f"The table name '{table_name}' in the '{file_name}' file is not a valid name.\
                               valid table names are {allowed_names}"
        )


def check_sheet_name(path, file_name, ids):

    """Checks if the sheets in the parameter files have valid names when 
    reading the data
    """

    file = pd.ExcelFile(r"{}/{}.xlsx".format(path, file_name))
    sheet_list = file.sheet_names
    allowed_list = []

    for key, value in ids.items():

        allowed_list.append(value["sheet_name"])

    for sheet in sheet_list:

        if sheet not in allowed_list:

            raise WrongSheetName(
                f"The sheet name '{sheet}' in the '{file_name}' file is not a valid name.\
                               valid sheet names are '{allowed_list}'"
            )


def check_tech_category(tech_table, allowed_categories, file_name):

    """Checks if the given technology categories are within the acceptable
    tech categories of the model
    """

    for tech_ctgry in tech_table["Tech_category"]:

        if tech_ctgry not in allowed_categories:

            raise WrongTechCategory(
                f"'{tech_ctgry}' category in Technologies table\
                                    in '{file_name}' file is not a valid technology category.\
                                        Valied categories are {allowed_categories}"
            )


def check_carrier_type(carr_table, allowed_types, file_name):

    """Checks if the given carrier types are within the acceptable
    carrier types of the model
    """

    for carr_type in carr_table["Carr_type"]:

        if carr_type not in allowed_types:

            raise WrongCarrierType(
                f"'{carr_type}' type in Carriers table in '{file_name}' file is not a valid carrier type. Valied types are {allowed_types}"
            )


def check_mapping_values(
    mapping_table,
    mapping_name,
    reference_table,
    reference_name,
    mapping_col,
    reference_col,
    file_name,
):

    """Checks if the specified carriers and technologies in the carrier input
    and carrier output tables have valid names
    """

    if not set(mapping_table[mapping_col]).issubset(
        set(reference_table[reference_col])
    ):

        raise WrongMappingData(
            f"There is an invalid name in '{mapping_col}' column of '{mapping_name}' table, in the '{file_name}'\
                               set file. Check the consistency between '{mapping_name}' table and '{reference_name}' table"
        )


def check_mapping_ctgry(
    mapping_table, table_name, technologies_table, tech_ctgry, file_name
):

    """Checks if there are valid technology categories in the carrier input and
    carrier output tables
    """
    for tech in mapping_table["Technology"]:

        if (
            technologies_table.loc[technologies_table["Technology"] == tech][
                "Tech_category"
            ].item()
            == tech_ctgry
        ):

            raise WrongMappingTech(
                f"Technologies with '{tech_ctgry}' category cannot be included in '{table_name}' table.\
                                   Modify '{table_name}' table in the '{file_name}' set file."
            )


def check_years_mode_consistency(mode, main_years):

    """Checks if the number of years is valid based on the given optimization
    mode
    """

    if mode == "Operation":

        if len(main_years) != 1:

            raise WrongNumberOfYears(
                f"The number of years is invalid.The '{mode}' optimization mode of the energy system\
                                     can be analyzed only with 'one year' time horizon"
            )
# -*- coding: utf-8 -*- This module contains a series of functions for checking the possible mistakes in the input data to raise the apporpriate error and inform the user. Checks if the columns in the set files have valid names Checks if the indices and columns in the parameter files have valid names Checks if there are nan values in the set and parameter tables and sheets Checks if the tables in the set files have valid names Checks if the sheets in the parameter files have valid names when      reading the data Checks if the given technology categories are within the acceptable     tech categories of the model Checks if the given carrier types are within the acceptable     carrier types of the model Checks if the specified carriers and technologies in the carrier input     and carrier output tables have valid names Checks if there are valid technology categories in the carrier input and     carrier output tables Checks if the number of years is valid based on the given optimization     mode