from modbus import Modbus
from mb_registers import reg_table
from colorama import Fore
import time
import random
from datetime import datetime, timedelta, timezone

models = {0x100: 'MDIO_88', 0x200: 'MAO_8', 0x300: 'MAI_12'}
test_state = {0: 'No Test', 1: 'Test OK', 2: 'Test FAIL'}


class IO_SysParams:
    
    SYS_TEST_OK = 0x0001
    SAVE_SYS_SETTINGS = 0x0001
    SAVE_SETTIGNS = 0x0001
    
    def __init__(self, modbus: Modbus):
        self.modbus = modbus

        self.MODEL_MDIO_88 = 0x0100
        self.MODEL_MAO_8 = 0x0200
        self.MODEL_MAI_12 = 0x0300

        t = datetime.now(timezone.utc).astimezone()
        self.utc_offset = t.utcoffset() // timedelta(seconds=1)
        

    def get_system_vars(self):
        """Запрос системных настроек и параметров"""

        print(Fore.LIGHTMAGENTA_EX + "\nSystem settings and params:\n")

        # Модель
        model = self.modbus.read_holding_registers(reg_table['model'], 1)[0]
        print("Model:       ", Fore.LIGHTMAGENTA_EX + models[model])

        # Дата производства    
        prod_date = self.modbus.read_uint32_holding(reg_table['prod_date'])
        t = time.gmtime(prod_date)
        print("Prod date:   ", Fore.LIGHTMAGENTA_EX + "{}.{}.{} {}:{}:{}".format(t.tm_mday, t.tm_mon, t.tm_year,
                                                      t.tm_hour, t.tm_min, t.tm_sec))

        # Серийный номер
        serial_number = self.modbus.read_uint32_holding(reg_table['serial_number'])
        print("SN:          ", Fore.LIGHTMAGENTA_EX + str(serial_number))

        # Версия ПО
        fw_bytes = b''
        data = self.modbus.read_holding_registers(reg_table['fw_ver'], 4)
        fw_raw = list(data)
        fw_raw.reverse()
        for i in fw_raw:
            fw_bytes += i.to_bytes(2, 'little')

        fw = fw_bytes.decode('utf-8')
        print("FW version:  ", Fore.LIGHTMAGENTA_EX + fw)

        # Статус тестирования
        status = self.modbus.read_holding_registers(reg_table['test_status'], 1)[0]
        print("Test status: ", Fore.LIGHTMAGENTA_EX + test_state[status])

        # Локальное время модуля
        t = time.ctime(self.get_rtc()/1000 - self.utc_offset)
        print("Local time : ", Fore.LIGHTMAGENTA_EX + t)

    def set_system_vars(self, password: int):
        """Установка системных настроек"""
        # Отправка пароля для разблокирования доступа к системным настройкам
        print("Send password...")
        self.modbus.write_holding_register(reg_table['password'], password)
        time.sleep(0.1)

        # Дата производства. На день назад от текущего момента.
        prod_time = int(time.time()) - time.timezone - 3600*24
        print("Set production date: ", prod_time)
        self.modbus.write_uint32(reg_table['prod_date'], prod_time)

        # Серийный номер
        sn = random.randint(10000, 1000000)
        print("Set SN: ", sn)
        self.modbus.write_uint32(reg_table['serial_number'], sn)

        # Статус тестирования
        print("Set test status: Test OK")
        self.modbus.write_holding_register(reg_table['test_status'], self.SYS_TEST_OK)

        # Команда сохранения системных настроек
        print("Save system settings...")
        self.modbus.write_holding_register(reg_table['save_sys_settings'], self.SAVE_SYS_SETTINGS)

    def save_sattings(self):
        self.modbus.write_holding_register(reg_table['param_manager'], self.SAVE_SETTIGNS)

    def get_uptime(self):
        return self.modbus.read_uint32_holding(reg_table['uptime'])

    def get_rtc(self):
        return self.modbus.read_uint64_holding(reg_table['rtc'])

    def set_rtc(self):
        """Установить текущее время"""
        t = int((time.time() + self.utc_offset) * 1000)
        self.modbus.write_uint64(reg_table['rtc'], t)

# def set_manager_register(dev: IO_Module, commands: list):
#     foo = 0
#     for command in commands:
#         foo |= command
#     print(foo)
    
#     # dev.write_holding_register(reg_table['param_manager'])


def main():
    pass

if __name__ == '__main__':
    main()