# -*- coding: utf-8 -*-
"""
@file   pdec_handler.py
@brief  Test commanding of PDEC Handler
@author J. Meier
@date   22.11.2021
"""
import enum

from spacepackets.ecss.tc import PusTelecommand
from tmtccmd.tc import DefaultPusQueueHelper

from tmtccmd.tc.pus_20_fsfw_param import create_load_param_cmd
from tmtccmd.tc.pus_8_fsfw_funccmd import create_action_cmd
from tmtccmd.pus.s20_fsfw_param_defs import create_scalar_u8_parameter

from tmtccmd.config.tmtc import (
    tmtc_definitions_provider,
    TmtcDefinitionWrapper,
    OpCodeEntry,
)

from eive_tmtc.config.definitions import CustomServiceList


class CommandId:
    # prints the clcw to the console. Useful for debugging
    PRINT_CLCW = bytearray([0x0, 0x0, 0x0, 0x0])
    # Print PDEC monitor register
    PRINT_PDEC_MON = bytearray([0x0, 0x0, 0x0, 0x1])


class ParameterId(enum.IntEnum):
    POSITIVE_WINDOW = 0
    NEGATIVE_WINDOW = 1


class ActionId(enum.IntEnum):
    RESET_NO_INIT = 2
    RESET_WITH_INIT = 3


class OpCode:
    PRINT_CLCW = "print_clcw"
    PRINT_MON_REG = "print_mon_reg"
    POSITIVE_WINDOW = "positive_window"
    NEGATIVE_WINDOW = "negative_window"
    RESET_WITH_INIT = "reset_with_init"
    RESET_NO_INIT = "reset_no_init"


class Info:
    PRINT_CLCW = "Will cause the OBSW to print the current CLCW to the debug console"
    PRINT_MON_REG = (
        "Will cause the OBSW to print the PDEC monitor register to the console"
    )
    POSITIVE_WINDOW = "Change positive window parameter for AD frames"
    NEGATIVE_WINDOW = "Change negative window parameter for AD frames"
    RESET_WITH_INIT = "Reset with full initialization"
    RESET_NO_INIT = "Reset with mandatory initialization"


def pack_pdec_handler_test(
    object_id: bytearray, q: DefaultPusQueueHelper, op_code: str
):
    q.add_log_cmd(f"Testing PDEC handler with object id: {object_id.hex()}")
    prefix = "PDEC Handler "
    if op_code == OpCode.PRINT_CLCW:
        q.add_log_cmd(f"{prefix}: {Info.PRINT_CLCW}")
        command = object_id + CommandId.PRINT_CLCW
        q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
    if op_code == OpCode.PRINT_MON_REG:
        q.add_log_cmd(f"{prefix}: {Info.PRINT_MON_REG}")
        command = object_id + CommandId.PRINT_PDEC_MON
        q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=command))
    if op_code == OpCode.POSITIVE_WINDOW:
        q.add_log_cmd(f"{prefix}: {Info.POSITIVE_WINDOW}")
        pw = int(input("Specify positive window to set: "))
        q.add_pus_tc(
            create_load_param_cmd(
                create_scalar_u8_parameter(
                    object_id,
                    0,
                    ParameterId.POSITIVE_WINDOW,
                    pw,
                ).pack()
            )
        )
    if op_code == OpCode.NEGATIVE_WINDOW:
        q.add_log_cmd(f"{prefix}: {Info.NEGATIVE_WINDOW}")
        nw = int(input("Specify negative window to set: "))
        q.add_pus_tc(
            create_load_param_cmd(
                create_scalar_u8_parameter(
                    object_id,
                    0,
                    ParameterId.NEGATIVE_WINDOW,
                    nw,
                ).pack()
            )
        )
    if op_code == OpCode.RESET_NO_INIT:
        q.add_log_cmd(f"{prefix}: {Info.RESET_NO_INIT}")
        q.add_pus_tc(
            create_action_cmd(object_id=object_id, action_id=ActionId.RESET_NO_INIT)
        )
    if op_code == OpCode.RESET_WITH_INIT:
        q.add_log_cmd(f"{prefix}: {Info.RESET_WITH_INIT}")
        q.add_pus_tc(
            create_action_cmd(object_id=object_id, action_id=ActionId.RESET_WITH_INIT)
        )


@tmtc_definitions_provider
def add_pdec_cmds(defs: TmtcDefinitionWrapper):
    oce = OpCodeEntry()
    oce.add(OpCode.PRINT_CLCW, Info.PRINT_CLCW)
    oce.add(OpCode.PRINT_MON_REG, Info.PRINT_MON_REG)
    oce.add(OpCode.POSITIVE_WINDOW, Info.POSITIVE_WINDOW)
    oce.add(OpCode.NEGATIVE_WINDOW, Info.NEGATIVE_WINDOW)
    oce.add(OpCode.RESET_WITH_INIT, Info.RESET_WITH_INIT)
    oce.add(OpCode.RESET_NO_INIT, Info.RESET_NO_INIT)
    defs.add_service(CustomServiceList.PDEC_HANDLER.value, "PDEC Handler", oce)