import struct

from pus_tm.defs import PrintWrapper
from tmtccmd.util.tmtc_printer import FsfwTmTcPrinter


def handle_eng_set(printer: FsfwTmTcPrinter, hk_data: bytes):
    pw = PrintWrapper(printer)
    header_list = [
        "Digital Voltage [mV]",
        "Analog Voltage [mV]",
        "Digital Current [mA]",
        "Analog Current [mA]",
        "Coil Current X [mA]",
        "Coil Current Y [mA]",
        "Coil Current Z [mA]",
        "Coil X Temperature [°C]",
        "Coil Y Temperature [°C]",
        "Coil Z Temperature [°C]",
        "Coil Z Temperature [°C]",
        "MCU Temperature [°C]",
    ]
    digital_voltage = struct.unpack("!H", hk_data[0:2])[0]
    analog_voltage = struct.unpack("!H", hk_data[2:4])[0]
    digital_current = struct.unpack("!f", hk_data[4:8])[0]
    analog_current = struct.unpack("!f", hk_data[8:12])[0]
    coil_x_current = struct.unpack("!f", hk_data[12:16])[0]
    coil_y_current = struct.unpack("!f", hk_data[16:20])[0]
    coil_z_current = struct.unpack("!f", hk_data[20:24])[0]
    coil_x_temperature = struct.unpack("!H", hk_data[24:26])[0]
    coil_y_temperature = struct.unpack("!H", hk_data[26:28])[0]
    coil_z_temperature = struct.unpack("!H", hk_data[30:32])[0]
    mcu_temperature = struct.unpack("!H", hk_data[32:34])[0]

    validity_buffer = hk_data[42:]
    content_list = [
        digital_voltage,
        analog_voltage,
        digital_current,
        analog_current,
        coil_x_current,
        coil_y_current,
        coil_z_current,
        coil_x_temperature,
        coil_y_temperature,
        coil_z_temperature,
        mcu_temperature,
    ]
    num_of_vars = len(header_list)
    pw.dlog(str(header_list))
    pw.dlog(str(content_list))
    printer.print_validity_buffer(validity_buffer=validity_buffer, num_vars=num_of_vars)


def handle_calibrated_mtm_measurement(printer: FsfwTmTcPrinter, hk_data: bytes):
    pw = PrintWrapper(printer)
    header_list = [
        "Calibrated MTM X [nT]",
        "Calibrated MTM Y [nT]",
        "Calibrated MTM Z [nT]",
        "Coild actuation status",
    ]
    mtm_x = struct.unpack("!I", hk_data[0:4])[0]
    mtm_y = struct.unpack("!I", hk_data[4:8])[0]
    mtm_z = struct.unpack("!I", hk_data[8:12])[0]
    coil_actuation_status = hk_data[12]
    validity_buffer = hk_data[12:]
    content_list = [mtm_x, mtm_y, mtm_z, coil_actuation_status]
    num_of_vars = len(header_list)
    pw.dlog(str(header_list))
    pw.dlog(str(content_list))
    printer.print_validity_buffer(validity_buffer=validity_buffer, num_vars=num_of_vars)


def handle_raw_mtm_measurement(printer: FsfwTmTcPrinter, hk_data: bytes):
    pw = PrintWrapper(printer)
    header_list = [
        "Raw MTM X [nT]",
        "Raw MTM Y [nT]",
        "Raw MTM Z [nT]",
        "Coild actuation status",
    ]
    mtm_x = struct.unpack("!f", hk_data[0:4])[0]
    mtm_y = struct.unpack("!f", hk_data[4:8])[0]
    mtm_z = struct.unpack("!f", hk_data[8:12])[0]
    coil_actuation_status = hk_data[12]
    validity_buffer = hk_data[12:]
    content_list = [mtm_x, mtm_y, mtm_z, coil_actuation_status]
    num_of_vars = len(header_list)
    pw.dlog(str(header_list))
    pw.dlog(str(content_list))
    printer.print_validity_buffer(validity_buffer=validity_buffer, num_vars=num_of_vars)


def handle_self_test_data(printer: FsfwTmTcPrinter, hk_data: bytes):
    pw = PrintWrapper(printer)
    header_list = [
        "Init Err",
        "Init Raw Mag X [nT]",
        "Init Raw Mag Y [nT]",
        "Init Raw Mag Z [nT]",
        "Init Cal Mag X [nT]",
        "Init Cal Mag Y [nT]",
        "Init Cal Mag Z [nT]",
        "Init Coil X Current [mA]",
        "Init Coil Y Current [mA]",
        "Init Coil Z Current [mA]",
        "Init Coil X Temperature [°C]",
        "Init Coil Y Temperature [°C]",
        "Init Coil Z Temperature [°C]",
        "Err",
        "Raw Mag X [nT]",
        "Raw Mag Y [nT]",
        "Raw Mag Z [nT]",
        "Cal Mag X [nT]",
        "Cal Mag Y [nT]",
        "Cal Mag Z [nT]",
        "Coil X Current [mA]",
        "Coil Y Current [mA]",
        "Coil Z Current [mA]",
        "Coil X Temperature [°C]",
        "Coil Y Temperature [°C]",
        "Coil Z Temperature [°C]",
        "Fina Err",
        "Fina Raw Mag X [nT]",
        "Fina Raw Mag Y [nT]",
        "Fina Raw Mag Z [nT]",
        "Fina Cal Mag X [nT]",
        "Fina Cal Mag Y [nT]",
        "Fina Cal Mag Z [nT]",
        "Fina Coil X Current [mA]",
        "Fina Coil Y Current [mA]",
        "Fina Coil Z Current [mA]",
        "Fina Coil X Temperature [°C]",
        "Fina Coil Y Temperature [°C]",
        "Fina Coil Z Temperature [°C]",
    ]
    # INIT step (no coil actuation)
    init_err = hk_data[0]
    init_raw_mag_x = struct.unpack("!f", hk_data[1:5])[0]
    init_raw_mag_y = struct.unpack("!f", hk_data[5:9])[0]
    init_raw_mag_z = struct.unpack("!f", hk_data[9:13])[0]
    init_cal_mag_x = struct.unpack("!f", hk_data[13:17])[0]
    init_cal_mag_y = struct.unpack("!f", hk_data[17:21])[0]
    init_cal_mag_z = struct.unpack("!f", hk_data[21:25])[0]
    init_coil_x_current = struct.unpack("!f", hk_data[25:29])[0]
    init_coil_y_current = struct.unpack("!f", hk_data[29:33])[0]
    init_coil_z_current = struct.unpack("!f", hk_data[33:37])[0]
    init_coil_x_temperature = struct.unpack("!H", hk_data[37:39])[0]
    init_coil_y_temperature = struct.unpack("!H", hk_data[39:41])[0]
    init_coil_z_temperature = struct.unpack("!H", hk_data[41:43])[0]

    # Actuation step
    err = hk_data[43]
    raw_mag_x = struct.unpack("!f", hk_data[44:48])[0]
    raw_mag_y = struct.unpack("!f", hk_data[48:52])[0]
    raw_mag_z = struct.unpack("!f", hk_data[52:56])[0]
    cal_mag_x = struct.unpack("!f", hk_data[56:60])[0]
    cal_mag_y = struct.unpack("!f", hk_data[60:64])[0]
    cal_mag_z = struct.unpack("!f", hk_data[64:68])[0]
    coil_x_current = struct.unpack("!f", hk_data[68:72])[0]
    coil_y_current = struct.unpack("!f", hk_data[72:76])[0]
    coil_z_current = struct.unpack("!f", hk_data[76:80])[0]
    coil_x_temperature = struct.unpack("!H", hk_data[80:82])[0]
    coil_y_temperature = struct.unpack("!H", hk_data[82:84])[0]
    coil_z_temperature = struct.unpack("!H", hk_data[84:86])[0]

    # FINA step (no coil actuation)
    fina_err = hk_data[86]
    fina_raw_mag_x = struct.unpack("!f", hk_data[87:91])[0]
    fina_raw_mag_y = struct.unpack("!f", hk_data[91:95])[0]
    fina_raw_mag_z = struct.unpack("!f", hk_data[95:99])[0]
    fina_cal_mag_x = struct.unpack("!f", hk_data[99:103])[0]
    fina_cal_mag_y = struct.unpack("!f", hk_data[103:107])[0]
    fina_cal_mag_z = struct.unpack("!f", hk_data[107:111])[0]
    fina_coil_x_current = struct.unpack("!f", hk_data[111:115])[0]
    fina_coil_y_current = struct.unpack("!f", hk_data[115:119])[0]
    fina_coil_z_current = struct.unpack("!f", hk_data[119:123])[0]
    fina_coil_x_temperature = struct.unpack("!H", hk_data[123:125])[0]
    fina_coil_y_temperature = struct.unpack("!H", hk_data[125:127])[0]
    fina_coil_z_temperature = struct.unpack("!H", hk_data[127:129])[0]

    validity_buffer = hk_data[129:]
    content_list = [
        init_err,
        init_raw_mag_x,
        init_raw_mag_y,
        init_raw_mag_z,
        init_cal_mag_x,
        init_cal_mag_y,
        init_cal_mag_z,
        init_coil_x_current,
        init_coil_y_current,
        init_coil_z_current,
        init_coil_x_temperature,
        init_coil_y_temperature,
        init_coil_z_temperature,
        err,
        raw_mag_x,
        init_raw_mag_y,
        raw_mag_z,
        cal_mag_x,
        cal_mag_y,
        cal_mag_z,
        coil_x_current,
        coil_y_current,
        coil_z_current,
        coil_x_temperature,
        coil_y_temperature,
        coil_z_temperature,
        fina_err,
        fina_raw_mag_x,
        fina_raw_mag_y,
        fina_raw_mag_z,
        fina_cal_mag_x,
        fina_cal_mag_y,
        fina_cal_mag_z,
        fina_coil_x_current,
        fina_coil_y_current,
        fina_coil_z_current,
        fina_coil_x_temperature,
        fina_coil_y_temperature,
        fina_coil_z_temperature,
    ]
    num_of_vars = len(header_list)
    pw.dlog(str(header_list))
    pw.dlog(str(content_list))
    printer.print_validity_buffer(validity_buffer=validity_buffer, num_vars=num_of_vars)