import os
import json
import time
import pandas as pd
from datetime import datetime
from azure.iot.device import IoTHubDeviceClient
from kairos_to_IoT_Hub_data_push import KairosDataPush

# COMMON CONSTANTS
TIME_INTERVAL = 60
EQUIPMENT = "Equipment"
MACHINE = "Machine"
PARAMETER_NAME_KEY = "Parameter Name"
TAG_ID_KEY = "Tag ID"
DATA_KEY = "data"

CONNECTION_STRING = "HostName=utpod-iot-001.azure-devices.net;" \
                    "DeviceId=edgedevice001;" \
                    "SharedAccessKey=14i0N1gRlO0cQEBZM4vN7J63JfuHsDYzIfU+7JFZngs="

EXCEL_FILE_PATH = "Data/Kairos/kairos_tags_data.xlsx"
VAL_KEY = "val"
DQ_KEY = "dq"
TA_KEY = "ta"
TH_KEY = "th"

# CREATING DATAFRAME FROM EXCEL PATH
tag_sheet_df = pd.read_csv("Data/Apollo/tags_download_002.csv")
data_sheet_df = pd.read_csv("Data/Apollo/ATL-Data-IPQC_002.csv")


class SDKIoTHubIntegration:
    """
    Class: This is the class for pushing events to Azure IoT Hub
    """

    def __init__(self):
        self.kairos_data_obj = KairosDataPush()
        self.mapping_json = self.kairos_data_obj.mapping_json

    def iot_hub_client_init(self):
        """
        Connection of IoT Hub using connection string
        :return:
        """
        client = None
        try:
            print("Initiating - iot_hub_client_init method")
            client = IoTHubDeviceClient.create_from_connection_string(
                CONNECTION_STRING)
            print("Connected - iot_hub_client_init method")
        except Exception as err:
            print("Exception in iot_hub_client_init: ", str(err))
        return client

    def iot_hub_client_telemetry_sample_run(self):
        """
        IoT Hub device sending periodic messages
        :return:
        """
        try:
            print("START: IoT Hub device data push")

            # Connection to IoT Hub using connection strings
            client = self.iot_hub_client_init()

            while True:
                message_counter = 1

                # Getting Data from Kairos and Creating CSV from the Tag Data
                csv_excel_path, column_list = self.kairos_data_obj.getting_kairos_data(
                    excel_file_path=EXCEL_FILE_PATH)

                tag_list, kairos_data_df = self.kairos_data_obj.reading_csv_excel_file(
                    csv_excel_path=csv_excel_path)

                # Iterating over each data in data_sheet
                for each_row in range(len(data_sheet_df)):
                    final_json = {
                        "data": {},
                        "site_id": "site_101",
                        "gw_id": "gw_118",
                        "pd_id": "pd_247",
                        "retain_flag": True,
                        "timestamp": str(int(time.time()) * 1000),
                        "processed_timestamp": str(datetime.now())[:-2],
                        "msg_id": int(message_counter),
                        "ver": 1.2,
                        "a_id": "ilens_device_100",
                        "d_id": "kuJj7HZeeNPQLsfgu82t2w",
                        "p_id": "project_390",
                        "topic": "ilens/monitor/live"
                    }

                    """ Iterating over each tags for Apollo Tyre XL Data """
                    for each_tags in range(len(tag_sheet_df)):
                        if str(tag_sheet_df.loc[each_tags, EQUIPMENT]).split("-")[
                            -1] == \
                                str(data_sheet_df.loc[each_tags, MACHINE]):

                            data_point = None
                            try:
                                # Creating a datapoint
                                data_point = data_sheet_df.loc[
                                    each_row, str(tag_sheet_df.loc[each_tags,
                                                                   PARAMETER_NAME_KEY]).replace(
                                        " ", "_")]

                                # final JSON with tag values
                                final_json[DATA_KEY][
                                    tag_sheet_df.loc[each_tags, TAG_ID_KEY]] = {
                                    "val": int(data_point),
                                    "dq": 1,
                                    "ta": str(tag_sheet_df.loc[each_tags,
                                                               PARAMETER_NAME_KEY]).replace(
                                        " ", "")}
                            except:
                                if data_point:
                                    # if data points are present for tag in data csv
                                    final_json[DATA_KEY][
                                        tag_sheet_df.loc[each_tags, TAG_ID_KEY]] = {
                                        "val": data_point,
                                        "dq": 1,
                                        "ta": str(tag_sheet_df.loc[
                                                      each_tags, PARAMETER_NAME_KEY]).replace(
                                            " ", "")
                                    }
                                else:
                                    # if data points are not present for
                                    # tag in data csv
                                    final_json[DATA_KEY][
                                        tag_sheet_df.loc[each_tags, TAG_ID_KEY]] = {
                                        "val": 0,
                                        "dq": 2,
                                        "ta": str(tag_sheet_df.loc[
                                                      each_tags, PARAMETER_NAME_KEY]).replace(
                                            " ", "")
                                    }

                    """ Iterating over each data for Kairos Data """
                    # Iterating over each tags in tag_sheet
                    for each_columns in column_list:
                        data_point = kairos_data_df.loc[each_row, each_columns]
                        try:
                            # final JSON with tag values
                            final_json[DATA_KEY][each_columns] = {
                                VAL_KEY: float(data_point),
                                DQ_KEY: 1,
                                TA_KEY: str(
                                    self.mapping_json[each_columns][TA_KEY]).replace(
                                    " ", ""),
                                TH_KEY: self.mapping_json[each_columns][TH_KEY]
                            }
                        except:
                            if data_point != "None":
                                final_json[DATA_KEY][each_columns] = {
                                    VAL_KEY: data_point,
                                    DQ_KEY: 1,
                                    TA_KEY: str(self.mapping_json[each_columns][
                                                    TA_KEY]).replace(" ", ""),
                                    TH_KEY: self.mapping_json[each_columns][TH_KEY]
                                }
                            else:
                                final_json[DATA_KEY][each_columns] = {
                                    VAL_KEY: None,
                                    DQ_KEY: 2,
                                    TA_KEY: str(self.mapping_json[each_columns][
                                                    TA_KEY]).replace(" ", ""),
                                    TH_KEY: self.mapping_json[each_columns][TH_KEY]
                                }

                    # Pushing Data To Cloud
                    client.send_message(json.dumps(final_json))
                    print("Message sent: \n{}".format(final_json))

                    # Time Frequency For Data
                    time.sleep(TIME_INTERVAL)
                    message_counter += 1

                    if message_counter == 1000:
                        message_counter = 1

                # Deleting CSV file
                try:
                    print(f"Removing CSV file: {csv_excel_path}")
                    os.remove(csv_excel_path)
                except Exception as err:
                    print("Exception in deleting csv/excel file", str(err))
                break

        except KeyboardInterrupt:
            print("STOP: IoT Hub device data push")


if __name__ == "__main__":
    cloud_to_device_obj = SDKIoTHubIntegration()
    cloud_to_device_obj.iot_hub_client_telemetry_sample_run()
