import enum

from config.definitions import CustomServiceList
from tmtccmd.config import TmtcDefinitionWrapper, OpCodeEntry
from tmtccmd.config.tmtc import tmtc_definitions_provider
from tmtccmd.tc import DefaultPusQueueHelper
from tmtccmd.tc.pus_200_fsfw_modes import Modes
from tmtccmd.tc.pus_3_fsfw_hk import (
    make_sid,
    generate_one_diag_command,
    generate_one_hk_command,
)

from .common import command_mode
from config.object_ids import TCS_BOARD_ASS_ID, TCS_CONTROLLER


class OpCodes:
    TCS_BOARD_ASS_NORMAL = ["0", "normal"]
    TCS_BOARD_ASS_OFF = ["1", "off"]
    REQUEST_SENSOR_TEMP_SET = ["2", "temps"]


class Info:
    REQUEST_SENSOR_TEMP_SET = "Request HK set of primary sensor temperatures"
    TCS_BOARD_ASS_NORMAL = "Switching TCS board assembly on"
    TCS_BOARD_ASS_OFF = "Switching TCS board assembly off"


class SetIds(enum.IntEnum):
    PRIMARY_SENSORS = 0
    DEVICE_SENSORS = 1
    SUS_TEMP_SENSORS = 2


@tmtc_definitions_provider
def add_tcs_cmds(defs: TmtcDefinitionWrapper):
    oce = OpCodeEntry()
    oce.add(
        keys=OpCodes.TCS_BOARD_ASS_NORMAL,
        info=Info.TCS_BOARD_ASS_NORMAL,
    )
    oce.add(
        keys=OpCodes.TCS_BOARD_ASS_OFF,
        info=Info.TCS_BOARD_ASS_OFF,
    )
    oce.add(keys=OpCodes.REQUEST_SENSOR_TEMP_SET, info=Info.REQUEST_SENSOR_TEMP_SET)
    defs.add_service(
        name=CustomServiceList.TCS.value,
        info="TCS Board Assembly",
        op_code_entry=oce,
    )


def pack_tcs_sys_commands(q: DefaultPusQueueHelper, op_code: str):
    if op_code in OpCodes.REQUEST_SENSOR_TEMP_SET:
        sensor_set_sid = make_sid(TCS_CONTROLLER, SetIds.PRIMARY_SENSORS)
        q.add_log_cmd(Info.REQUEST_SENSOR_TEMP_SET)
        q.add_pus_tc(generate_one_hk_command(sensor_set_sid))
    pack_tcs_ass_cmds(q, op_code)


def pack_tcs_ass_cmds(q: DefaultPusQueueHelper, op_code: str):
    if op_code in OpCodes.TCS_BOARD_ASS_NORMAL:
        command_mode(
            object_id=TCS_BOARD_ASS_ID,
            mode=Modes.NORMAL,
            submode=0,
            q=q,
            info=Info.TCS_BOARD_ASS_NORMAL,
        )
    if op_code in OpCodes.TCS_BOARD_ASS_OFF:
        command_mode(
            object_id=TCS_BOARD_ASS_ID,
            mode=Modes.OFF,
            submode=0,
            q=q,
            info=Info.TCS_BOARD_ASS_OFF,
        )