from dotenv import load_dotenv
import os
import sys
from configparser import ConfigParser, BasicInterpolation
import yaml

# Configuration File Constants
_application_conf = f"./conf/application.conf"
_default_conf = f"./config.env"
data_conf = f"./conf/data.yml"
training_data = f"./data/training.csv"

load_dotenv(dotenv_path=_default_conf)
DATA_CONFIGURATION_FILE = r"./conf/data_config.yml"


class EnvInterpolation(BasicInterpolation):
    """
    Interpolation which expands environment variables in values.
    """

    def before_get(self, parser, section, option, value, defaults):
        value = super().before_get(parser, section, option, value, defaults)

        if not os.path.expandvars(value).startswith("$"):
            return os.path.expandvars(value)
        else:
            return


try:
    config = ConfigParser(interpolation=EnvInterpolation())
    config.read(_application_conf)
except Exception as e:
    print(f"Error while loading the config: {e}")
    print("Failed to Load Configuration. Exiting!!!")
    sys.exit()


class Logging:
    level = config.get("LOGGING", "level", fallback="INFO")
    level = level if level else "INFO"
    tb_flag = config.getboolean("LOGGING", "traceback", fallback=True)
    tb_flag = tb_flag if tb_flag is not None else True


# Configuration Variables
# Kairos Configuration Variables
KAIROS_DB_HOST = config["KAIROS_DB"]["uri"]
# Postgres Configuration Variables
POSTGRES_URI = config["POSTGRES"]["postgres_uri"]
# Kafka Configuration Variables
KAFKA_HOST = config["KAFKA"]["kafka_host"]
KAFKA_PORT = config["KAFKA"]["kafka_port"]
KAFKA_TOPIC = config["KAFKA"]["kafka_topic"]

# Read the configuration file

with open(data_conf, "r") as _cf:
    _config = yaml.full_load(_cf)

with open(DATA_CONFIGURATION_FILE, "r") as _cf:
    _compliance_config = yaml.full_load(_cf)

MODEL = _config["model"]
PARAMETER_INFO = _config["parameter"]
PARAMETER_INPUT = _config["model_input_features"]
PARAMETER_OUTPUT = _config["model_output_features"]
OUTPUT_DATA = _config["output"]
OUTPUT_PARAMETER_QUICK_MAP_INFO = OUTPUT_DATA["quick_map"]
OUTPUT_SITE_ID = OUTPUT_DATA["site"]

REQUIRED_TZ = config['TIMEZONE']['required_tz']

COMPLIANCE_OUTPUT_DATA = _compliance_config["output"]
COMPLIANCE_OUTPUT_PARAMETER_QUICK_MAP_INFO = COMPLIANCE_OUTPUT_DATA["quick_map"]

LOGIN_TOKEN = config["API"]["login_token"]

COL_RENAMER = _config['column_renamer']
COLUMN_RENAMER = {v: k for k, v in COL_RENAMER.items()}


class MlflowMetaData:
    MLFLOW_TRACKING_URI = config['MLFLOW']['mlflow_tracking_uri']
    MLFLOW_TRACKING_USERNAME = config['MLFLOW']['mlflow_tracking_username']
    MLFLOW_TRACKING_PASSWORD = config['MLFLOW']['mlflow_tracking_password']
    AZURE_STORAGE_CONNECTION_STRING = config['MLFLOW']['azure_storage_connection_string']
    AZURE_STORAGE_ACCESS_KEY = config['MLFLOW']['azure_storage_access_key']
    EXPERIMENT_NAME = config['MLFLOW']['experiment_name']
    RUN_NAME = config['MLFLOW']['run_name']
    MODEL_NAME = config['MLFLOW']['model_name']
    RETRAIN_PARAM_UNIT = config['MLFLOW']['retrain_param_unit']
    RETRAIN_PARAM_VALUE = config['MLFLOW']['retrain_param_value']


class PycaretMetaData:
    LIST_OF_MODELS = config['PYCARET']['list_of_models']
    SEARCH_LIBRARY = config['PYCARET']['search_library']
    COMPARISON_METRIC = config['PYCARET']['comparison_metric']
