#!/usr/bin/env python
import argparse
from flask import Flask
from gunicorn.app.base import BaseApplication
import os
import urllib.parse


def parse_args():
    parser = argparse.ArgumentParser(description='Websocket server')
    parser.add_argument('--ml_board_host', type=str, help='Specification of mlboard host', required=True)
    parser.add_argument('--ml_board_port', type=int, help='Specification of mlboard host', required=True)
    parser.add_argument('--rest_endpoint', type=str, help='Specification of REST endpoint (format: protocol://host:port)', required=True)
    parser.add_argument('--ws_endpoint', type=str, help='Specification of weboscket endpoint (format: protocol://host:port)', required=True)
    parser.add_argument('--run_id', type=str, help='Id of the run that is to be analyzed', required=True)
    args = parser.parse_args()
    ml_board_host = args.ml_board_host
    ml_board_port = args.ml_board_port
    rest_endpoint = args.rest_endpoint
    ws_endpoint = args.ws_endpoint
    run_id = args.run_id
    return ml_board_host, ml_board_port, rest_endpoint, ws_endpoint, run_id


class StandaloneApplication(BaseApplication):

    def __init__(self, app, options=None):
        self.options = options or {}
        self.application = app
        super().__init__()

    def load_config(self):
        config = {key: value for key, value in self.options.items()
                  if key in self.cfg.settings and value is not None}
        for key, value in config.items():
            self.cfg.set(key.lower(), value)

    def load(self):
        return self.application


def run_ml_board(ml_board_host: str, ml_board_port: str, rest_endpoint: str, ws_endpoint: str, run_id: str):
    static_folder_path = os.path.abspath(os.path.join(__file__, "../../../frontend/dashboard/build"))
    app = Flask(__name__, static_folder=static_folder_path, static_url_path='/')

    @app.route('/')
    def index():
        return app.send_static_file('index.html')

    # app.run(host=f"{ml_board_host}", port=ml_board_port)

    options = {
        'bind': f"{ml_board_host}:{ml_board_port}",
        'workers': 1
    }
    rest_endpoint_encoded = urllib.parse.quote(rest_endpoint)
    ws_endpoint_encoded = urllib.parse.quote(ws_endpoint)
    run_id_encoded = urllib.parse.quote(run_id)
    url = f"http://{ml_board_host}:{ml_board_port}?rest_endpoint={rest_endpoint_encoded}&ws_endpoint={ws_endpoint_encoded}&run_id={run_id_encoded}"
    print(f"====> ACCESS MLBOARD VIA {url}")
    StandaloneApplication(app, options).run()


ml_board_host, ml_board_port, rest_endpoint, ws_endpoint, run_id = parse_args()

run_ml_board(ml_board_host=ml_board_host, ml_board_port=ml_board_port, rest_endpoint=rest_endpoint, ws_endpoint=ws_endpoint, run_id=run_id)
