import logging

from LCM.TethysLcmTypes import LrauvLcmMessage

logger = logging.getLogger("backseat")


class LcmHandlerBase:

    @staticmethod
    def decode(msg):
        """
        Decode LrauvLcmMessage LCM packet.

        :param msg: coded LrauvLcmMessage LCM packet
        :return: decoded LrauvLcmMessage LCM packet
        """
        return LrauvLcmMessage.decode(msg)

    @staticmethod
    def get_timestamp_sec(msg: LrauvLcmMessage):
        return msg.epochMillisec / 1000.0

    @staticmethod
    def get_item_names(msg: LrauvLcmMessage):
        """
        Extract all LrauvLcmMessage item names.

        :param msg: decoded LrauvLcmMessage LCM packet
        :return: list containing LrauvLcmMessage item names
        """
        names = []
        for array in [msg.byteArrays, msg.intArrays, msg.floatArrays, msg.doubleArrays, msg.stringArrays]:
            for item in array:
                if item.name:
                    names.append(item.name)
        return names

    @staticmethod
    def get_variable(name: str, msg: LrauvLcmMessage):
        """
        Extract LrauvLcmMessage item matching the inputted name.

        :param name: variable name to extract
        :param msg: decoded LrauvLcmMessage LCM packet
        :return: byte/string/float/int/double LrauvLcmMessage item if name is matched, otherwise returns False
        """
        for vec in [msg.byteArrays, msg.intArrays, msg.floatArrays, msg.doubleArrays, msg.stringArrays]:
            for item in vec:
                if item.name == name:
                    return item
        logger.error("Failed to get array. Variable name '{}' is unknown.".format(name))
        return False

    @staticmethod
    def get_byte_array(name: str, msg: LrauvLcmMessage):
        """
        Extract byteArray item matching the inputted name.

        :param name: variable name to extract
        :param msg: decoded LrauvLcmMessage LCM packet
        :return: byte array item if name is matched, otherwise returns False
        """
        for item in msg.byteArrays:
            if item.name == name:
                return item
        logger.error("Failed to get byte array. Variable name '{}' is unknown.".format(name))
        return False

    @staticmethod
    def get_float_array(name: str, msg: LrauvLcmMessage):
        """
        Extract floatArray item matching the inputted name.

        :param name: variable name to extract
        :param msg: decoded LrauvLcmMessage LCM packet
        :return: float array item if name is matched, otherwise returns False
        """
        for item in msg.floatArrays:
            if item.name == name:
                return item
        logger.error("Failed to get float array. Variable name '{}' is unknown.".format(name))
        return False

    @staticmethod
    def get_int_array(name: str, msg: LrauvLcmMessage):
        """
        Extract intArray item matching the inputted name.

        :param name: variable name to extract
        :param msg: decoded LrauvLcmMessage LCM packet
        :return: int array item if name is matched, otherwise returns False
        """
        for item in msg.intArrays:
            if item.name == name:
                return item
        logger.error("Failed to get int array. Variable name '{}' is unknown.".format(name))
        return False

    @staticmethod
    def get_double_array(name: str, msg: LrauvLcmMessage):
        """
        Extract doubleArray item matching the inputted name.

        :param name: variable name to extract
        :param msg: decoded LrauvLcmMessage LCM packet
        :return: double array item if name is matched, otherwise returns False
        """
        for item in msg.doubleArrays:
            if item.name == name:
                return item
        logger.error("Failed to get double array. Variable name '{}' is unknown.".format(name))
        return False

    @staticmethod
    def get_string_array(name: str, msg: LrauvLcmMessage):
        """
        Extract stringArray item matching the inputted name.

        :param name: variable name to extract
        :param msg: decoded LrauvLcmMessage LCM packet
        :return: string vector item if name is matched, otherwise returns False
        """
        for item in msg.stringArrays:
            if item.name == name:
                return item
        logger.error("Failed to get string array. Variable name '{}' is unknown.".format(name))
        return False
