import enum

from config.definitions import CustomServiceList
from tmtccmd.config.tmtc import (
    tmtc_definitions_provider,
    TmtcDefinitionWrapper,
    OpCodeEntry,
)
from tmtccmd.tc import service_provider
from tmtccmd.tc.decorator import ServiceProviderParams
from tmtccmd.tc.pus_200_fsfw_modes import Modes
from config.object_ids import ACS_BOARD_ASS_ID

from tmtc.common import pack_mode_cmd_with_info


class AcsOpCodes:
    ACS_ASS_A_SIDE = ["0", "a"]
    ACS_ASS_B_SIDE = ["1", "b"]
    ACS_ASS_DUAL_MODE = ["2", "d"]
    ACS_ASS_OFF = ["3", "off"]
    ACS_ASS_A_ON = ["4", "ao"]
    ACS_ASS_B_ON = ["5", "bo"]
    ACS_ASS_DUAL_ON = ["6", "do"]


class DualSideSubmodes(enum.IntEnum):
    A_SIDE = 0
    B_SIDE = 1
    DUAL_SIDE = 2


@service_provider(CustomServiceList.ACS_BRD_ASS)
def pack_acs_command(p: ServiceProviderParams):
    op_code = p.op_code
    q = p.queue_helper
    if op_code in AcsOpCodes.ACS_ASS_A_SIDE:
        pack_mode_cmd_with_info(
            object_id=ACS_BOARD_ASS_ID,
            mode=Modes.NORMAL,
            submode=DualSideSubmodes.A_SIDE,
            q=q,
            info="Switching to ACS board assembly A side",
        )
    if op_code in AcsOpCodes.ACS_ASS_B_SIDE:
        pack_mode_cmd_with_info(
            object_id=ACS_BOARD_ASS_ID,
            mode=Modes.NORMAL,
            submode=DualSideSubmodes.B_SIDE,
            q=q,
            info="Switching to ACS board assembly B side",
        )
    if op_code in AcsOpCodes.ACS_ASS_DUAL_MODE:
        pack_mode_cmd_with_info(
            object_id=ACS_BOARD_ASS_ID,
            mode=Modes.NORMAL,
            submode=DualSideSubmodes.DUAL_SIDE,
            q=q,
            info="Switching to ACS board assembly dual mode",
        )
    if op_code in AcsOpCodes.ACS_ASS_A_ON:
        pack_mode_cmd_with_info(
            object_id=ACS_BOARD_ASS_ID,
            mode=Modes.ON,
            submode=DualSideSubmodes.A_SIDE,
            q=q,
            info="Switching ACS board assembly A side on",
        )
    if op_code in AcsOpCodes.ACS_ASS_B_ON:
        pack_mode_cmd_with_info(
            object_id=ACS_BOARD_ASS_ID,
            mode=Modes.ON,
            submode=DualSideSubmodes.B_SIDE,
            q=q,
            info="Switching ACS board assembly B side on",
        )
    if op_code in AcsOpCodes.ACS_ASS_DUAL_ON:
        pack_mode_cmd_with_info(
            object_id=ACS_BOARD_ASS_ID,
            mode=Modes.ON,
            submode=DualSideSubmodes.B_SIDE,
            q=q,
            info="Switching ACS board assembly dual side on",
        )
    if op_code in AcsOpCodes.ACS_ASS_OFF:
        pack_mode_cmd_with_info(
            object_id=ACS_BOARD_ASS_ID,
            mode=Modes.OFF,
            submode=0,
            q=q,
            info="Switching to ACS board assembly off",
        )


@tmtc_definitions_provider
def add_acs_board_cmds(defs: TmtcDefinitionWrapper):
    oce = OpCodeEntry()
    oce.add(
        keys=AcsOpCodes.ACS_ASS_A_SIDE,
        info="Switch to ACS board A side",
    )
    oce.add(
        keys=AcsOpCodes.ACS_ASS_B_SIDE,
        info="Switch to ACS board B side",
    )
    oce.add(
        keys=AcsOpCodes.ACS_ASS_DUAL_MODE,
        info="Switch to ACS board dual mode",
    )
    oce.add(
        keys=AcsOpCodes.ACS_ASS_A_ON,
        info="Switch ACS board A side on",
    )
    oce.add(
        keys=AcsOpCodes.ACS_ASS_B_ON,
        info="Switch ACS board B side on",
    )
    oce.add(
        keys=AcsOpCodes.ACS_ASS_DUAL_ON,
        info="Switch ACS board dual mode on",
    )
    oce.add(
        keys=AcsOpCodes.ACS_ASS_OFF,
        info="Switch off ACS board",
    )
    defs.add_service(
        name=CustomServiceList.ACS_BRD_ASS.value,
        info="ACS Board Assemblie",
        op_code_entry=oce,
    )