################################################################################
#
# Copyright (c) 2019, the Perspective Authors.
#
# This file is part of the Perspective library, distributed under the terms of
# the Apache License 2.0.  The full license can be found in the LICENSE file.
#
import os
import os.path
import logging
import tornado.ioloop
import threading
import random 
import glob

from datetime import date, datetime , timedelta
#import datetime
import time
import threading
import uvicorn

from fastapi import FastAPI, WebSocket
from fastapi import  Request
from fastapi import UploadFile
from fastapi import File

import shutil
from pathlib import Path
from fastapi.middleware.cors import CORSMiddleware
from starlette.responses import FileResponse
from starlette.staticfiles import StaticFiles
from datetime import datetime


import perspective
from perspective import Server
#from perspective import Table
from perspective.handlers.starlette import PerspectiveStarletteHandler
def static_nodemodules_handler(rest_of_path):
    if rest_of_path.startswith("@perspective-dev"):
        return FileResponse("node_modules/{}".format(rest_of_path))
    return FileResponse("node_modules/@finos/{}".format(rest_of_path))



here = os.path.abspath(os.path.dirname(__file__))
file_path = os.path.join(
    here, "..", "..", "node_modules", "superstore-arrow", "superstore.arrow"
)


datestr = date.today().strftime('%Y%m%d')



nkytable=None
lasttime = datetime.now()
def update():
    global nkytable
  
    global lasttime
    idxmid = random.randint(4000, 4100)
    idxcls = random.randint(4000, 4100)
    futmid  = random.randint(4000, 4100)

    if datetime.now()  > lasttime + timedelta(seconds=10):
        print("update " , idxmid , lasttime.strftime("%H:%M:%S")  ) 
        lasttime = datetime.now() ; 
        nkytable.update([{"IdxMid": idxmid   , "IdxBid" : idxcls , "IdxAsk" : futmid  ,  "lastUpdate" :lasttime.strftime("%H:%M:%S")  }] ) 




def perspective_thread(manager):
    """Perspective application thread starts its own tornado IOLoop, and
    adds the table with the name "data_source_one", which will be used
    in the front-end."""
    psp_loop = tornado.ioloop.IOLoop()
    client = manager.new_local_client()
    global nkytable

    nkytable = client.table({"IdxMid": float , "IdxBid": float , "IdxAsk": float, "lastUpdate":str} , limit=3000 , name="data_source_one") 
    callback = tornado.ioloop.PeriodicCallback(callback=update, callback_time=500)
    callback.start()
    psp_loop.start()


def make_app():
    manager = perspective.Server()
    thread = threading.Thread(target=perspective_thread, args=(manager,))
    thread.daemon = True
    thread.start()



    async def websocket_handler(websocket: WebSocket):
        handler = PerspectiveStarletteHandler(perspective_server=manager, websocket=websocket)
        await handler.run()

    static_html_files = StaticFiles(directory="./", html=True)
    app = FastAPI()
    app.add_api_websocket_route("/websocket", websocket_handler)
    app.get("/node_modules/{rest_of_path:path}")(static_nodemodules_handler)
    app.mount("/", static_html_files)
    app.add_middleware(
            CORSMiddleware,
            allow_origins=["*"],
            allow_credentials=True,
            allow_methods=["*"],
            allow_headers=["*"],
            )

    return app 



if __name__ == "__main__":
    app = make_app()
    logging.critical("Listening on http://qlp03:25060")
    logging.getLogger("uvicorn.access").setLevel(logging.DEBUG)
    uvicorn.run(app, host="10.229.51.103", port=25060 ) 
