#!/usr/bin/python3
##!/usr/bin/env python3

# -*- coding: utf-8 -*-
#############################################################################
# @package ad_hmi
# @brief xviz server of python package ad_hmi.
#############################################################################
# @author <NAME>
# @copyright (c) All rights reserved.
#############################################################################

import sys, os, logging
import asyncio, json
import traceback
import time

sys.path.append(os.path.join(os.path.dirname(__file__), '..'))

from xviz_avs.server import XVIZServer, XVIZBaseSession

from AdasScenario import AdasScenario
# from dc_listener import DCListener

class ScenarioSession(XVIZBaseSession):
    FPS = 20            # fps, 20Hz
    T_SLOT = 1 / FPS    # task time slot

    def __init__(self, socket, request, scenario=AdasScenario()):
        super().__init__(socket, request)
        self._scenario = scenario
        self._socket = socket

    def on_connect(self):
        print("Connected!")
        self._scenario.on_connect()
 
    def on_disconnect(self):
        print("Disconnect!")
        self._scenario.on_disconnect()

    async def main(self):
        print('main')

        metadata = self._scenario.get_metadata()
        if metadata:
            await self._socket.send(metadata)

        t = 0
        while True:
            t_start = time.time()

            message = self._scenario.get_message(t)
            if message:
                await self._socket.send(message)
            else:
                pass # print('x', end='')

            t_elapsed = time.time() - t_start

            t_sleep = 0
            if self.T_SLOT > t_elapsed:
                t_sleep = self.T_SLOT - t_elapsed
            else:
                print('Data processing overtaken..., t_elapsed={: ^8,.6f}, T_SLOT={: ^8,.6f}'.format(t_elapsed, self.T_SLOT))
            t += t_sleep
            await asyncio.sleep(t_sleep if not self._scenario.is_in_mp() else self.T_SLOT/10)

class ScenarioHandler:
    def __init__(self):
        pass

    def __call__(self, socket, request):
        print('new session started, request=', request, ', socket local=', socket.local_address, ', remote=', socket.remote_address)

        return ScenarioSession(socket, request)


if __name__ == "__main__":
    # init ros_listener
    # listener = DCListener()
    # listener.init_subscribe()

    # init logging
    handler = logging.StreamHandler(sys.stdout)
    handler.setLevel(logging.DEBUG)
    logging.getLogger("xviz-server").addHandler(handler)

    # init xviz_server
    server = XVIZServer(ScenarioHandler(), port=8081)
    # FIXME: config the host with api if possible.
    server._serve_options['host'] = '0.0.0.0'
    print('Server listen at {}:{} ...'.format(server._serve_options['host'], server._serve_options['port']))

    if len(sys.argv) > 1 and sys.argv[1] == 'mp':
        AdasScenario.spawn_mp()

    # main loop
    loop = asyncio.get_event_loop()
    loop.run_until_complete(server.serve())
    loop.run_forever()

    
