import enum
from typing import Dict, Tuple

from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.config.object_ids import PL_SUBSYSTEM_ID
from spacepackets.ecss import PusTelecommand
from eive_tmtc.tmtc.common import pack_mode_cmd_with_info
from tmtccmd.config import TmtcDefinitionWrapper, OpCodeEntry
from tmtccmd.config.tmtc import tmtc_definitions_provider
from tmtccmd.tc import service_provider
from tmtccmd.tc.decorator import ServiceProviderParams
from tmtccmd.tc.pus_200_fsfw_modes import Subservice as ModeSubservice


class OpCode(str, enum.Enum):
    OFF = "off"
    REPORT_ALL_MODES = "report_modes"


class PayloadMode(enum.IntEnum):
    OFF = 0


class Info(str, enum.Enum):
    OFF = "Off Command"
    REPORT_ALL_MODES = "Report all modes"


HANDLER_LIST: Dict[str, Tuple[int, str]] = {
    OpCode.OFF: (PayloadMode.OFF, Info.OFF),
}


@service_provider(CustomServiceList.PL_SS)
def build_acs_subsystem_cmd(p: ServiceProviderParams):
    op_code = p.op_code
    q = p.queue_helper
    info_prefix = "ACS Subsystem"
    if op_code in OpCode.REPORT_ALL_MODES:
        q.add_log_cmd(f"{info_prefix}: {Info.REPORT_ALL_MODES}")
        q.add_pus_tc(
            PusTelecommand(
                service=200,
                subservice=ModeSubservice.TC_MODE_ANNOUNCE_RECURSIVE,
                app_data=PL_SUBSYSTEM_ID,
            )
        )
    mode_info_tup = HANDLER_LIST.get(op_code)
    if mode_info_tup is None:
        return
    pack_mode_cmd_with_info(
        object_id=PL_SUBSYSTEM_ID,
        info=f"{info_prefix}: {mode_info_tup[1]}",
        submode=0,
        mode=mode_info_tup[0],
        q=q,
    )


@tmtc_definitions_provider
def add_payload_subsystem_cmds(defs: TmtcDefinitionWrapper):
    oce = OpCodeEntry()
    oce.add(OpCode.OFF, Info.OFF)
    oce.add(OpCode.REPORT_ALL_MODES, Info.REPORT_ALL_MODES)
    defs.add_service(CustomServiceList.PL_SS, "Payload Subsystem", oce)