# Copyright 2019-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import absolute_import
import socketio
import psutil
import time
import datetime

from threading import Timer
from gevent import pywsgi
from geventwebsocket.handler import WebSocketHandler
from multiprocessing import Process
from multistructlog import create_logger
from cord_workflow_controller_client.probe import GREETING, EVENT_EMIT
from cord_workflow_controller_client.manager \
    import (WORKFLOW_KICKSTART,
            WORKFLOW_REGISTER, WORKFLOW_REGISTER_ESSENCE, WORKFLOW_LIST, WORKFLOW_LIST_RUN,
            WORKFLOW_CHECK, WORKFLOW_REMOVE, WORKFLOW_REMOVE_RUN, WORKFLOW_REPORT_NEW_RUN)
from cord_workflow_controller_client.workflow_run \
    import (WORKFLOW_RUN_NOTIFY_EVENT, WORKFLOW_RUN_COUNT_EVENTS, WORKFLOW_RUN_FETCH_EVENT)


"""
Run a dummy socket.io server as a separate process.
serve_forever() blocks until the process is killed,
so I had to use multi-process approach.
"""

log = create_logger()

# Socket IO
sio = None

manager_clients = {}
workflows = {}
workflow_essences = {}
workflow_runs = {}
workflow_run_clients = {}
seq_no = 1


class repeatableTimer():
    def __init__(self, time, handler, arg):
        self.time = time
        self.handler = handler
        self.arg = arg
        self.thread = Timer(self.time, self.on_tick)

    def on_tick(self):
        self.handler(self.arg)
        self.thread = Timer(self.time, self.on_tick)
        self.thread.start()

    def start(self):
        self.thread.start()

    def cancel(self):
        self.thread.cancel()


def make_query_string_dict(query_string):
    obj = {}
    params = query_string.split('&')
    for param in params:
        kv = param.split('=')
        key = kv[0]
        val = kv[1]
        obj[key] = val

    return obj


def _send_kickstart_event(sid):
    global seq_no

    workflow_id = 'dummy_workflow_%d' % seq_no
    workflow_run_id = 'dummy_workflow_run_%d' % seq_no

    seq_no += 1
    log.info('sending a kickstart event to sid %s' % sid)
    sio.emit(
        event=WORKFLOW_KICKSTART,
        data={
            'workflow_id': workflow_id,
            'workflow_run_id': workflow_run_id,
            'timestamp': str(datetime.datetime.now())
        },
        room=sid
    )


def _send_notify_event(sid):
    global seq_no

    topic = 'topic_%s' % seq_no
    message = {
        'sample_key': 'sample_value'
    }
    seq_no += 1

    run_client = workflow_run_clients[sid]
    if run_client:
        workflow_run_id = run_client['workflow_run_id']
        workflow_run = workflow_runs[workflow_run_id]
        if workflow_run:
            workflow_run['queue'].append({
                'topic': topic,
                'message': message
            })

            log.info('sending a notify event to sid %s' % sid)
            sio.emit(
                event=WORKFLOW_RUN_NOTIFY_EVENT,
                data={
                    'topic': topic,
                    'timestamp': str(datetime.datetime.now())
                },
                room=sid
            )


def _handle_event_connect(sid, query):
    sio.emit(GREETING, {})

    global last_client_action_time
    last_client_action_time = datetime.datetime.now

    # if the client is a manager, send kickstart events every 3 sec
    if query['type'] == 'workflow_manager':
        log.info('manager (%s) is connected' % sid)
        kickstart_timer = repeatableTimer(2, _send_kickstart_event, sid)
        manager_clients[sid] = {
            'kickstart_timer': kickstart_timer
        }

        kickstart_timer.start()
    elif query['type'] == 'workflow_run':
        log.info('workflow run (%s) is connected' % sid)
        notify_event_timer = repeatableTimer(2, _send_notify_event, sid)
        workflow_run_clients[sid] = {
            'workflow_id': query['workflow_id'],
            'workflow_run_id': query['workflow_run_id'],
            'notify_event_timer': notify_event_timer
        }

        notify_event_timer.start()


def _handle_event_disconnect(sid):
    if sid in manager_clients:
        log.info('manager (%s) is disconnected' % sid)
        if manager_clients[sid]['kickstart_timer']:
            manager_clients[sid]['kickstart_timer'].cancel()

        del manager_clients[sid]

    if sid in workflow_run_clients:
        log.info('workflow run (%s) is disconnected' % sid)
        if workflow_run_clients[sid]['notify_event_timer']:
            workflow_run_clients[sid]['notify_event_timer'].cancel()

        del workflow_run_clients[sid]

    global last_client_action_time
    last_client_action_time = datetime.datetime.now


def _get_req_id(body):
    req_id = 101010
    if 'req_id' in body:
        req_id = int(body['req_id'])
    return req_id


def _handle_event_workflow_reg(sid, body):
    data = {
        'req_id': _get_req_id(body)
    }

    if 'workflow' in body:
        workflow = body['workflow']
        workflow_id = workflow['id']

        if workflow_id in workflows:
            # already exist
            data['error'] = True
            data['result'] = False
            data['message'] = 'workflow is already registered'
        else:
            log.info('manager (%s) registers a workflow (%s)' % (sid, workflow_id))
            workflows[workflow_id] = workflow

            data['error'] = False
            data['result'] = True
    else:
        data['error'] = True
        data['result'] = False
        data['message'] = 'workflow is not in the message body'

    log.info('returning a result for workflow register event to sid %s' % sid)
    sio.emit(
        event=WORKFLOW_REGISTER,
        data=data,
        room=sid
    )


def _handle_event_workflow_reg_essence(sid, body):
    data = {
        'req_id': _get_req_id(body)
    }

    if 'essence' in body:
        essence = body['essence']
        for wid in essence:
            workflow_essence = essence[wid]
            if 'dag' in workflow_essence and 'dag_id' in workflow_essence['dag']:
                dag = workflow_essence['dag']
                workflow_id = dag['dag_id']

                if workflow_id in workflow_essences or workflow_id in workflows:
                    # already exist
                    data['error'] = True
                    data['result'] = False
                    data['message'] = 'workflow is already registered'
                else:
                    log.info('manager (%s) registers a workflow (%s)' % (sid, workflow_id))
                    workflow_essences[workflow_id] = workflow_essence

                    data['error'] = False
                    data['result'] = True
            else:
                data['error'] = True
                data['result'] = False
                data['message'] = 'essence is not in the message body'
    else:
        data['error'] = True
        data['result'] = False
        data['message'] = 'essence is not in the message body'

    log.info('returning a result for workflow essence register event to sid %s' % sid)
    sio.emit(
        event=WORKFLOW_REGISTER_ESSENCE,
        data=data,
        room=sid
    )


def _handle_event_workflow_list(sid, body):
    data = {
        'req_id': _get_req_id(body)
    }

    workflow_ids = []

    for workflow_id in workflows:
        workflow_ids.append(workflow_id)

    for workflow_id in workflow_essences:
        workflow_ids.append(workflow_id)

    data['error'] = False
    data['result'] = workflow_ids

    log.info('returning a result for workflow list event to sid %s' % sid)
    sio.emit(
        event=WORKFLOW_LIST,
        data=data,
        room=sid
    )


def _handle_event_workflow_run_list(sid, body):
    data = {
        'req_id': _get_req_id(body)
    }

    workflow_run_ids = []

    for workflow_run_id in workflow_runs:
        workflow_run_ids.append(workflow_run_id)

    data['error'] = False
    data['result'] = workflow_run_ids

    log.info('returning a result for workflow run list event to sid %s' % sid)
    sio.emit(
        event=WORKFLOW_LIST_RUN,
        data=data,
        room=sid
    )


def _handle_event_workflow_check(sid, body):
    data = {
        'req_id': _get_req_id(body)
    }

    if 'workflow_id' in body:
        workflow_id = body['workflow_id']
        if workflow_id in workflows:
            data['error'] = False
            data['result'] = True
        else:
            data['error'] = False
            data['result'] = False
    else:
        data['error'] = True
        data['result'] = False
        data['message'] = 'workflow_id is not in the message body'

    log.info('returning a result for workflow check event to sid %s' % sid)
    sio.emit(
        event=WORKFLOW_CHECK,
        data=data,
        room=sid
    )


def _handle_event_workflow_remove(sid, body):
    data = {
        'req_id': _get_req_id(body)
    }

    if 'workflow_id' in body:
        workflow_id = body['workflow_id']
        if workflow_id in workflows:

            hasWorkflowRuns = False
            for workflow_run_id in workflow_runs:
                workflow_run = workflow_runs[workflow_run_id]
                wid = workflow_run['workflow_id']
                if wid == workflow_id:
                    # there is a workflow run for the workflow id
                    hasWorkflowRuns = True
                    break

            if hasWorkflowRuns:
                data['error'] = False
                data['result'] = False
            else:
                del workflows[workflow_id]

                data['error'] = False
                data['result'] = True
        else:
            data['error'] = False
            data['result'] = False
    else:
        data['error'] = True
        data['result'] = False
        data['message'] = 'workflow_id is not in the message body'

    log.info('returning a result for workflow remove event to sid %s' % sid)
    sio.emit(
        event=WORKFLOW_REMOVE,
        data=data,
        room=sid
    )


def _handle_event_workflow_run_remove(sid, body):
    data = {
        'req_id': _get_req_id(body)
    }

    if 'workflow_id' in body and 'workflow_run_id' in body:
        # workflow_id = body['workflow_id']
        workflow_run_id = body['workflow_run_id']

        if workflow_run_id in workflow_runs:
            del workflow_runs[workflow_run_id]

            data['error'] = False
            data['result'] = True
        else:
            data['error'] = False
            data['result'] = False
    else:
        data['error'] = True
        data['result'] = False
        data['message'] = 'workflow_id or workflow_run_id is not in the message body'

    log.info('returning a result for workflow run remove event to sid %s' % sid)
    sio.emit(
        event=WORKFLOW_REMOVE_RUN,
        data=data,
        room=sid
    )


def _handle_event_new_workflow_run(sid, body):
    data = {
        'req_id': _get_req_id(body)
    }

    if 'workflow_id' in body and 'workflow_run_id' in body:
        workflow_id = body['workflow_id']
        workflow_run_id = body['workflow_run_id']

        log.info('manager (%s) started a new workflow (%s), workflow_run (%s)' % (sid, workflow_id, workflow_run_id))
        workflow_runs[workflow_run_id] = {
            'workflow_id': workflow_id,
            'workflow_run_id': workflow_run_id,
            'queue': []
        }

        data['error'] = False
        data['result'] = True
    else:
        data['error'] = True
        data['result'] = False
        data['message'] = 'workflow_id or workflow_run_id is not in the message body'

    log.info('returning a result for a new workflow run event to sid %s' % sid)
    sio.emit(
        event=WORKFLOW_REPORT_NEW_RUN,
        data=data,
        room=sid
    )


def _handle_event_workflow_run_count_events(sid, body):
    data = {
        'req_id': _get_req_id(body)
    }

    if 'workflow_id' in body and 'workflow_run_id' in body:
        # workflow_id = body['workflow_id']
        workflow_run_id = body['workflow_run_id']

        if workflow_run_id in workflow_runs:
            workflow_run = workflow_runs[workflow_run_id]
            queue = workflow_run['queue']
            count = len(queue)

            data['error'] = False
            data['result'] = count
        else:
            data['error'] = True
            data['result'] = 0
            data['message'] = 'cannot find workflow run'
    else:
        data['error'] = True
        data['result'] = 0
        data['message'] = 'workflow_id, workflow_run_id, task_id or status is not in the message body'

    log.info('returning a result for workflow run count events to sid %s' % sid)
    sio.emit(
        event=WORKFLOW_RUN_COUNT_EVENTS,
        data=data,
        room=sid
    )


def _handle_event_workflow_run_fetch_event(sid, body):
    data = {
        'req_id': _get_req_id(body)
    }

    if 'workflow_id' in body and 'workflow_run_id' in body and 'task_id' in body and 'topic' in body:
        # workflow_id = body['workflow_id']
        workflow_run_id = body['workflow_run_id']
        # task_id = body['task_id']
        topic = body['topic']

        if workflow_run_id in workflow_runs:
            workflow_run = workflow_runs[workflow_run_id]
            queue = workflow_run['queue']

            event = None
            for idx in range(len(queue)):
                if queue[idx]['topic'] == topic:
                    # found
                    event = queue.pop(idx)
                    break

            if event:
                data['error'] = False
                data['result'] = event
            else:
                data['error'] = False
                data['result'] = {}
        else:
            data['error'] = False
            data['result'] = False
            data['message'] = 'cannot find workflow run'
    else:
        data['error'] = True
        data['result'] = False
        data['message'] = 'workflow_id, workflow_run_id, task_id or topic is not in the message body'

    log.info('returning a result for workflow run fetch event to sid %s' % sid)
    sio.emit(
        event=WORKFLOW_RUN_FETCH_EVENT,
        data=data,
        room=sid
    )


def _handle_event_emit(sid, body):
    data = {
        'req_id': _get_req_id(body)
    }

    if 'topic' in body and 'message' in body:
        # workflow_id = body['workflow_id']
        topic = body['topic']
        message = body['message']

        log.info('probe topic %s - message %s' % (topic, message))

        data['error'] = False
        data['result'] = True
    else:
        data['error'] = True
        data['result'] = False
        data['message'] = 'topic or message is not in the message body'

    log.info('returning a result for event emit to sid %s' % sid)
    sio.emit(
        event=EVENT_EMIT,
        data=data,
        room=sid
    )


def _handle_event(event, sid, body):
    log.info('event %s - body %s (%s)' % (event, body, type(body)))


class ServerEventHandler(socketio.namespace.Namespace):
    def trigger_event(self, event, *args):
        sid = args[0]
        if event == 'connect':
            querystr = args[1]['QUERY_STRING']
            query = make_query_string_dict(querystr)
            _handle_event_connect(sid, query)
        elif event == 'disconnect':
            _handle_event_disconnect(sid)

        # manager
        elif event == WORKFLOW_REPORT_NEW_RUN:
            _handle_event_new_workflow_run(sid, args[1])
        elif event == WORKFLOW_REGISTER_ESSENCE:
            _handle_event_workflow_reg_essence(sid, args[1])
        elif event == WORKFLOW_REGISTER:
            _handle_event_workflow_reg(sid, args[1])
        elif event == WORKFLOW_LIST:
            _handle_event_workflow_list(sid, args[1])
        elif event == WORKFLOW_LIST_RUN:
            _handle_event_workflow_run_list(sid, args[1])
        elif event == WORKFLOW_CHECK:
            _handle_event_workflow_check(sid, args[1])
        elif event == WORKFLOW_REMOVE:
            _handle_event_workflow_remove(sid, args[1])
        elif event == WORKFLOW_REMOVE_RUN:
            _handle_event_workflow_run_remove(sid, args[1])

        # workflow run
        elif event == WORKFLOW_RUN_COUNT_EVENTS:
            _handle_event_workflow_run_count_events(sid, args[1])
        elif event == WORKFLOW_RUN_FETCH_EVENT:
            _handle_event_workflow_run_fetch_event(sid, args[1])
        elif event == EVENT_EMIT:
            _handle_event_emit(sid, args[1])
        else:
            _handle_event(event, args[0], args[1])


def _run(port):
    global sio
    sio = socketio.Server(ping_timeout=5, ping_interval=1)
    app = socketio.WSGIApp(sio)
    sio.register_namespace(ServerEventHandler('/'))

    server = pywsgi.WSGIServer(
        ('', port),
        app,
        handler_class=WebSocketHandler
    )

    server.serve_forever()


def start(port):
    p = Process(target=_run, args=(port, ))
    p.start()
    time.sleep(3)

    log.info('Dummy server is started!')
    return p


def stop(p):
    log.info('Stopping dummy server!')

    try:
        process = psutil.Process(p.pid)
        for proc in process.children(recursive=True):
            proc.kill()
        process.kill()
        p.join()
    except BaseException:
        pass
    except psutil.NoSuchProcess:
        pass

    # clean-up
    global sio, manager_clients, workflow_runs, seq_no
    sio = None
    manager_clients = {}
    workflow_runs = {}
    seq_no = 1

    time.sleep(3)

    log.info('Dummy server is stopped!')
