from spacepackets.ecss import PusTelecommand
from tmtccmd.config.tmtc import (
    CmdTreeNode,
)
from tmtccmd.pus.s201_fsfw_health import FsfwHealth, Subservice
from tmtccmd.tmtc import DefaultPusQueueHelper

from eive_tmtc.config.definitions import CustomServiceList
from eive_tmtc.tmtc.obj_prompt import prompt_object


class OpCode:
    SET_HEALTH = "set_health"
    ANNOUNCE_HEALTH_ALL = "read_health_all"
    ANNOUNCE_HEALTH = "read_health"


class Info:
    SET_HEALTH = "Set health of specific object"
    ANNOUNCE_HEALTH_ALL = "Read all health states"
    ANNOUNCE_HEALTH = "Read health state of one object"


def prompt_health() -> FsfwHealth:
    for item in FsfwHealth:
        print(f"{item}: {item.name}")
    health_idx = int(input("Please enter health by index: "))
    return FsfwHealth(health_idx)


def build_health_cmds(q: DefaultPusQueueHelper, cmd_str: str):
    if cmd_str == OpCode.SET_HEALTH:
        app_data = bytearray(prompt_object())
        health = prompt_health()
        app_data.append(health)
        q.add_log_cmd(Info.SET_HEALTH)
        q.add_pus_tc(
            PusTelecommand(
                service=201, subservice=Subservice.TC_SET_HEALTH, app_data=app_data
            )
        )
    elif cmd_str == OpCode.ANNOUNCE_HEALTH:
        app_data = bytearray(prompt_object())
        q.add_log_cmd(Info.ANNOUNCE_HEALTH)
        q.add_pus_tc(
            PusTelecommand(
                service=201, subservice=Subservice.TC_ANNOUNCE_HEALTH, app_data=app_data
            )
        )
    elif cmd_str == OpCode.ANNOUNCE_HEALTH_ALL:
        q.add_log_cmd(Info.ANNOUNCE_HEALTH_ALL)
        q.add_pus_tc(
            PusTelecommand(service=201, subservice=Subservice.TC_ANNOUNCE_HEALTH_ALL)
        )
    else:
        raise ValueError(
            f"unknown command string {cmd_str} for service {CustomServiceList.HEALTH}"
        )


def create_global_health_node() -> CmdTreeNode:
    health_node = CmdTreeNode("health", "Health Commands")
    health_node.add_child(
        CmdTreeNode(OpCode.ANNOUNCE_HEALTH_ALL, Info.ANNOUNCE_HEALTH_ALL)
    )
    health_node.add_child(CmdTreeNode(OpCode.ANNOUNCE_HEALTH, Info.ANNOUNCE_HEALTH))
    health_node.add_child(CmdTreeNode(OpCode.SET_HEALTH, Info.SET_HEALTH))
    return health_node