#! /usr/bin/env python
__author__ = "Ben Raanan"
__copyright__ = "Copyright 2021, MBARI"
__credits__ = ["MBARI"]
__license__ = "GPL-3.0"
__maintainer__ = "Ben Raanan"
__email__ = "byraanan at mbari.org"
__doc__ = '''

Defines an LCM publisher class for the LRAUV backseat helper service.

@author: __author__
@license: __license__
'''
import logging

import lcm

from LCM.DataRequest import LcmDataReq
from LCM.Publisher import LcmPublisher

logger = logging.getLogger("backseat")


class LcmDataRequester(LcmPublisher):
    """
    Issues data requests to Tethys LRAUV.

    """
    def __init__(self, lcm_instance: lcm.LCM, req_channel='tethys_data_request'):
        LcmPublisher.__init__(self, lcm_instance)
        # issue data requests on Tethys data req channel
        self.channel = req_channel
        self.req_list = []


    def add_request(self, var_name: str, channel=""):
        """
        Add variable to list of requested items.

        Creates a LcmDataReq object for the specified variable name.

        Note: LCM channel name will be inferred from the var name if unspecified.

        :param var_name: name of variable to request.
        :param channel: (optional) name of expected receiving LCM channel.
        :return: True upon successful add
        """
        for r in self.req_list:
            if r.name == var_name:
                # no duplicates allowed
                return False

        self.req_list.append(LcmDataReq(self.lc, var_name, channel))
        return True


    def remove_request(self, rm_name: str):
        """
        Remove variable from list of requested items.

        :param rm_name: name of variable to remove
        :return: void
        """
        for r in self.req_list:
            if r.name == rm_name:
                # announce data is no longer needed...
                self.add_byte(r.name, False, 'bool')
                self.publish(self.channel)
                self.clear_msg()
                # ...and remove from list
                self.req_list.remove(r)
                return


    def request(self, rx_data_timeout=60.0):
        """
        Issues LCM data request message to Tethys LRAUV for listed variables.

        :param rx_data_timeout: max time since last message was received.
                                Data requests will be resent if the time
                                since last rx is exceeded.
        :return: void
        """
        pub_request = False
        for r in self.req_list:

            if r.needs_request(rx_data_timeout):
                self.add_byte(r.name, True, 'bool')
                pub_request = True

        if pub_request:
            logger.info('Requesting data from LRAUV.')
            self.publish(self.channel)
            self.clear_msg()