# -*- coding: utf-8 -*-
"""
@file   reaction_wheels.py
@brief  Tests for the reaction wheel handler
@author J. Meier
@date   20.06.2021
"""
import struct
from tmtccmd.config.definitions import QueueCommands

from tmtccmd.tc.packer import TcQueueT
from spacepackets.ecss.tc import PusTelecommand
from pus_tc.service_200_mode import pack_mode_data


class RwSetIds:
    STATUS_SET_ID = 4
    TEMPERATURE_SET_ID = 8


class RwCommandIds:
    RESET_MCU = bytearray([0x0, 0x0, 0x0, 0x01])
    # Reads status information from reaction wheel into dataset with id 4
    GET_RW_STATUS = bytearray([0x0, 0x0, 0x0, 0x04])
    INIT_RW_CONTROLLER = bytearray([0x0, 0x0, 0x0, 0x05])
    SET_SPEED = bytearray([0x0, 0x0, 0x0, 0x06])
    # Reads temperature from reaction wheel into dataset with id 8
    GET_TEMPERATURE = bytearray([0x0, 0x0, 0x0, 0x08])
    GET_TM = bytearray([0x0, 0x0, 0x0, 0x09])


class SpeedDefinitions:
    RPM_100 = 1000
    RPM_5000 = 5000


class RampTime:
    MS_1000 = 1000


def pack_single_rw_test_into(
    object_id: bytearray, tc_queue: TcQueueT, op_code: str
) -> TcQueueT:
    tc_queue.appendleft(
        (
            QueueCommands.PRINT,
            "Testing reaction wheel handler with object id: 0x" + object_id.hex(),
        )
    )

    if op_code == "0" or op_code == "1":
        speed = int(input("Specify speed [0.1 RPM]: "))
        ramp_time = int(input("Specify ramp time [ms]: "))
        tc_queue.appendleft((QueueCommands.PRINT, "Reaction Wheel: Set speed"))
        command = pack_set_speed_command(object_id, speed, ramp_time)
        command = PusTelecommand(service=8, subservice=128, ssc=40, app_data=command)
        tc_queue.appendleft(command.pack_command_tuple())

    if op_code == "2":
        tc_queue.appendleft((QueueCommands.PRINT, "Reaction Wheel: Switch to mode on"))
        mode_data = pack_mode_data(object_id, 1, 0)
        command = PusTelecommand(service=200, subservice=1, ssc=41, app_data=mode_data)
        tc_queue.appendleft(command.pack_command_tuple())

    if op_code == "3":
        tc_queue.appendleft(
            (QueueCommands.PRINT, "Reaction Wheel: Switch to mode normal")
        )
        mode_data = pack_mode_data(object_id, 2, 0)
        command = PusTelecommand(service=200, subservice=1, ssc=42, app_data=mode_data)
        tc_queue.appendleft(command.pack_command_tuple())

    if op_code == "4":
        tc_queue.appendleft((QueueCommands.PRINT, "Reaction Wheel: Switch to mode off"))
        mode_data = pack_mode_data(object_id, 0, 0)
        command = PusTelecommand(service=200, subservice=1, ssc=43, app_data=mode_data)
        tc_queue.appendleft(command.pack_command_tuple())

    if op_code == "5":
        tc_queue.appendleft(
            (QueueCommands.PRINT, "Reaction Wheel: Send get-telemetry-command")
        )
        command = object_id + RwCommandIds.GET_TM
        command = PusTelecommand(service=8, subservice=128, ssc=44, app_data=command)
        tc_queue.appendleft(command.pack_command_tuple())
    return tc_queue


def pack_set_speed_command(
    object_id: bytearray, speed: int, ramp_time: int
) -> bytearray:
    """With this function a command is packed to set the speed of a reaction wheel
    @param object_id    The object id of the reaction wheel handler.
    @param speed   Valid speeds are [-65000, -1000] and [1000, 65000]. Values are specified in 0.1 * RPM
    @param ramp_time   The time after which the reaction wheel will reached the commanded speed. Valid times are
                       10 - 10000 ms
    """
    command_id = RwCommandIds.SET_SPEED
    command = bytearray()
    command = object_id + command_id
    command = command + struct.pack("!i", speed)
    command = command + ramp_time.to_bytes(length=2, byteorder="big")
    return command