#! /usr/bin/python3

import json
import rospy
from hri_actions_msgs.msg import Intent


class ApplicationController:
    def __init__(self) -> None:

        rospy.loginfo("[APPLICATION {{ id }}] initialising...")


        # this member variable will be set to 'True' if the application manager
        # or the user request the application to stop.
        self.cancellation_requested = False

        #######################################
        #
        # TODO: Add here any initialization steps
        # that should occurs only once.
        #


        rospy.loginfo(
            "[APPLICATION {{ id }}] Ready to start. Call action /applications/{{ id }}/control/ to start it."
        )

    def on_intent(self, msg):

        rospy.loginfo("[APPLICATION {{ id }}] Received an intent: %s" % msg.intent)

        #######################################
        #
        # TODO: Define here how your application
        # should react when receiving an user
        # intent.

        data = json.loads(msg.data) if msg.data else {}
        source = msg.source
        modality = msg.modality
        confidence = msg.confidence
        priority_hint = msg.priority

        #######################################
        #
        # If you do not need to process specific
        # intents, simply remove the corresponding
        # line(s).
        #

{% if intents %}
{% for intent in intents +%}
        # Intent {{ intent.intent }}: {{ intent.description }}
        {{ "if" if loop.index == 1 else "elif"}} msg.intent == Intent.{{ intent.intent }}:
{% if intent.required_thematic_roles %}
            # the 'data' dictionary should contain at least the following keys:
{% for role in intent.required_thematic_roles %}
            # - {{ role }}
{% endfor %}
{% endif %}
{% if intent.intent == "ENGAGE_WITH" and robot == "ARI" %}

            # As an example, we call here the TTS and play_motion action server
            # to implement a very simple behaviour when someone engages with the
            # robot.
            import actionlib
            from pal_interaction_msgs.msg import TtsAction, TtsGoal
            from play_motion_msgs.msg import PlayMotionAction, PlayMotionGoal

            tts = actionlib.SimpleActionClient('tts', TtsAction)
            play_motion = actionlib.SimpleActionClient('play_motion', PlayMotionAction)

            tts_goal = TtsGoal()
            tts_goal.rawtext.text = "Hello, I'm ARI. Nice to meet you!"
            tts_goal.rawtext.lang_id = "en_GB"

            tts.send_goal_and_wait(tts_goal)

            motion_goal = PlayMotionGoal(motion_name="wave")

            play_motion.send_goal_and_wait(motion_goal)

{% else %}
            pass
{% endif %}

{% endfor %}

        # custom intent?
        else:
            rospy.logwarn("I don't know how to process intent <%s>!" % msg.intent)
{% else %}
        # handle here the different intents
        if msg.intent == "your_intent" # or one of the Intent.msg constants
            pass

        # elif...

        else:
            rospy.logwarn("I don't know how to process intent <%s>!" % msg.intent)
{% endif %}

    def run(self, parameters = None) -> None:
        """
        The main 'blocking' task of your application. Implements the
        background processing of your applcation.

        Optionally, parameters can be passed to the application.

        This function should *not* return unless `self.cancellation_requested`
        is set to `True` (by the application manager).
        """

        self._intents_sub = rospy.Subscriber("/intents", Intent, self.on_intent)
        rospy.loginfo("[APPLICATION {{ id }}] running")

        #######################################
        #
        # TODO: Implement here any background
        # task required by your application.
        #
        # This function should *not* return unless
        # self.cancellation_requested is set to True
        #

        rate = rospy.Rate(1)  # 1Hz

        inc = 0
        while not self.cancellation_requested:

            rospy.loginfo(inc)
            inc += 1

            rate.sleep()

        self._intents_sub.unregister()
        rospy.loginfo("[APPLICATION {{ id }}] stopped")


