from pyrois.Service_Application_IF import Service_Application_IF
from pyrois import RoIS_Service, RoIS_HRI
from pyrois.RoIS_Common import Component_Status
from pyrois.RoIS_Service import Completed_Status

import logging
import queue
import threading
import time
import enum
import xmlrpc


class TaskKind(enum.Enum):
    NaviToUser  = 1
    NaviToGuide = 2
    End         = 3


class TaskState(object):
    __task_seq_table = {
        TaskKind.NaviToUser:  TaskKind.NaviToGuide,
        TaskKind.NaviToGuide: TaskKind.End,
        TaskKind.End:         TaskKind.End
    }

    def __init__(self, task_kind, status=None):
        self.task_kind = task_kind
        self.status = status

    def __repr__(self):
        return "<task_kind: {}, status: {}>".format(self.task_kind, self.status)

    def next(self):
        return TaskState.__task_seq_table[self.task_kind]


class Service(Service_Application_IF):
    def __init__(self, uri="http://localhost:8000", logger=None):
        super().__init__(uri)
        self.target_pos = "point_c"
        self.dest_pos   = "point_a"
        self.commandid_taskstate_table = {}

    def completed(self, command_id, status):
        task = self.commandid_taskstate_table[command_id]
        status = Completed_Status(status)
        task.status = status
        next_task = task.next()
        if next_task == TaskKind.NaviToGuide:
            self.start_navi_to_guide(self.dest_pos)
        elif next_task == TaskKind.End:
            print("Route Guide Finished !!")
        self.commandid_taskstate_table[command_id] = task
        print(self.commandid_taskstate_table)

    def notify_error(self, error_id, error_type):
        print('received error event {}({}) '.format( \
              error_id, RoIS_Service.ErrorType(error_type).name))

    def notify_event(self, event_id, event_type, subscribe_id, expire):
        print('received event {} {} {} {}'.format( \
              event_id, event_type, subscribe_id, expire))

    def start_navi_to_user(self, dest):
        (return_code, command_id) = self._proxy.set_parameter('Navigation', dest, "", "")
        stautus = RoIS_HRI.ReturnCode_t(return_code)
        self.commandid_taskstate_table[command_id] = TaskState(TaskKind.NaviToUser)

    def start_navi_to_guide(self, dest):
        (return_code, command_id) = self._proxy.set_parameter('Navigation', dest, "", "")
        stautus = RoIS_HRI.ReturnCode_t(return_code)
        self.commandid_taskstate_table[command_id] = TaskState(TaskKind.NaviToGuide)

    def run(self):
        self._proxy = xmlrpc.client.ServerProxy(self._uri)
        time.sleep(3)
        target_point = "point_c"
        self.start_navi_to_user(target_point)


if __name__ == '__main__':
    service = Service()
    print("Starting service..")
    service.run()
    print("Finish.")
