#!/usr/bin/env python3

# (Dummy) Speech_Recognition.py
# 

"""Speech_Recognition
"""

import sys
from six.moves import queue
from six.moves import xmlrpc_client
import time
from datetime import datetime
import threading

from pyrois import RoIS_Common, RoIS_HRI

if sys.version_info.major == 2:
    import SocketServer
    import SimpleXMLRPCServer

    class ThreadingXMLRPCServer(SocketServer.ThreadingMixIn, SimpleXMLRPCServer.SimpleXMLRPCServer):
        pass
else:
    import socketserver
    import xmlrpc.server

    class ThreadingXMLRPCServer(socketserver.ThreadingMixIn, xmlrpc.server.SimpleXMLRPCServer):
        """ThreadingXMLRPCServer
        """
        pass


class Command(RoIS_Common.Command):
    """Command
    """
    def __init__(self, c):
        self._component = c

    def start(self):
        status = RoIS_HRI.ReturnCode_t.OK.value
        return status

    def stop(self):
        status = RoIS_HRI.ReturnCode_t.OK.value
        return status

    def suspend(self):
        status = RoIS_HRI.ReturnCode_t.OK.value
        return status

    def resume(self):
        status = RoIS_HRI.ReturnCode_t.OK.value
        return status

    def set_parameter(self, languages, grammer, rule):
        self._component.Recognizable_Languages = recognizable_languages
        self._component.Languages = languages
        self._component.Grammer = grammer
        self._component.Rule = rule
        status = RoIS_HRI.ReturnCode_t.OK.value
        return status


class Query(RoIS_Common.Query):
    """Query
    """
    def __init__(self, c):
        self._component = c

    def component_status(self):
        status = RoIS_HRI.ReturnCode_t.OK.value
        c_status = RoIS_Common.Component_Status.UNINITIALIZED.value
        return (status, c_status)

    def get_parameter(self):
        status = RoIS_HRI.ReturnCode_t.OK.value
        return (status, self._component.Languages, self._component.Grammer, self._component.Rule)


class Event(RoIS_Common.Event):
    """Event
    """
    def __init__(self, c):
        self._component = c
        self.event_queue = queue.Queue()

    def poll_event(self):
        """poll_event
        """
        msg = self.event_queue.get()
        return msg

    def speech_recognized(self, timestamp, recognized_text):
        """speech_recognition
        """
        msg = xmlrpc_client.dumps((timestamp, recognized_text), 'speech_recognized')
        self.event_queue.put(msg)

    def speech_input_started(self, timestamp):
        msg = xmlrpc_client.dumps((timestamp), 'speech_input_started')
        self.event_queue.put(msg)

    def speech_input_finished(self, timestamp):
        msg = xmlrpc_client.dumps((timestamp), 'speech_input_finished')
        self.event_queue.put(msg)

import random
import rospy
from std_msgs.msg import String

class Speech_Recognition(Event, Command, Query):
    """Speech_Recognition
    """
    def __init__(self, c, robot_name):
        super(Speech_Recognition, self).__init__(c)
        self._component = c
        self._component.Recognizable_Languages = set("")
        self._component.Languages = set("English")
        self._component.Grammer = "" #???
        self._component.Rule = "" #???
        rospy.Subscriber(robot_name+"/detected_text", String, self.sr_callback)
        self.robot_name = robot_name

    def set_parameter(self, languages, grammer, rule):
        print("Speech_Recognition::set_parameter called.")
        #  th = threading.Thread(
                #  target=self.wait_and_send_speech_recognized_event,
                #  daemon=True)
        #  th.start()
        status = RoIS_HRI.ReturnCode_t.OK.value
        return status

    def wait_and_send_speech_recognized_event(self):
        detected_text = input("SR >>> ")
        delay_duration = random.randint(0, 5)
        time.sleep(delay_duration)
        self.speech_recognized(datetime.now(), [detected_text])

    def sr_callback(self, text):
        detected_text = text.data
        self.speech_recognized(datetime.now(), [detected_text])

    def speech_recognized(self, timestamp, recognized_text):
        """speech_recognition
        """
        msg = (timestamp, recognized_text, self.robot_name), 'speech_recognized'
        msg = xmlrpc_client.dumps(*msg)
        self.event_queue.put(msg)


class component:
    """component
    """
    def __init__(self):
        self._state = False


def example_sr(port, robot_name):
    """example_sr
    """
    c = component()
    sr = Speech_Recognition(c, robot_name)

    # start the XML-RPC server
    server = ThreadingXMLRPCServer(("0.0.0.0", port), logRequests=False)
    server.register_instance(sr)
    server.register_introspection_functions()
    server.register_multicall_functions()
    server.serve_forever()


if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("rosrun <this_package> <this_script> <port_num> <robot_name>")
        raise RuntimeError

    port, robot_name = int(sys.argv[1]), sys.argv[2]
    rospy.init_node('speech_recognition_component', anonymous=True)
    example_sr(port, robot_name)
