from screen import screenlive
import json, argparse
from flask import Flask, json
import threading
from time import sleep
from websockets.sync.server import serve
import websockets
import array
import time
from flask import render_template 

api = Flask(__name__)
watchers_last_seen = {}
web_users = {}
stream = False
freeze = False
debug = False

def current_time():
    return str(int(time.time()))

@api.route("/", methods=["GET"])
def web():
    return render_template('index.html')

@api.route("/off", methods=["GET"])
def streaOff():
    global stream
    stream=False
    return "True"

@api.route("/freeze", methods=["GET"])
def freeze_the_stream():
    global freeze
    if freeze == True:
        freeze=False
        return "un-frosen"
    else:
        freeze=True
        return "frosen"

@api.route("/on", methods=["GET"])
def streamOn():
    global stream
    stream=True
    return "True"

@api.route("/views", methods=["GET"])
def return_views():
    global watchers_last_seen
    return str(len(watchers_last_seen.keys()))

@api.route("/mode", methods=["GET"])
def mode():
    global watchers_last_seen
    return "streaming-"+str(stream)+"\n frozen-"+str(freeze)

def ws_server(websocket):
    global stream, watchers_last_seen
    if debug: print("WebSocket: Server Started.")
    try:
        while True:
            req=websocket.recv()
            if "%" in req:
                args= req.split("%")[1]
                args = dict(x.split("=") for x in args.split(";"))
                req = req.split("%")[0]
            if debug: print(req,"-----",args)
            match (req):
                case ("get_stream"):
                    if freeze == True:
                        websocket.send(f"freeze")
                    else:
                        if stream:
                            watchers_last_seen[args["uuid"]] = current_time()
                            websocket.send(f""+str(json.dumps([True, screenlive.gen()])))
                        else:
                            websocket.send(f"null")
                case ("web-site-user"):
                    users[args["uuid"]] = current_time()
                case (_):
                    websocket.send(f"null")
    except websockets.exceptions.ConnectionClosedOK:
        if debug: print("hungup")
    except websockets.ConnectionClosedError:
        if debug: print("Internal Server Error.")

def run_ws_server():
        with serve(ws_server, "0.0.0.0", 5621) as server:
            server.serve_forever()

def timeout_task():
    while True:
        for key,value in watchers_last_seen.items():
            if debug: print(key+"||||"+value)
            if (int(current_time())-int(value)) > 5:
                if debug: print(key+"is timed out")
                watchers_last_seen.pop(key)
                break
        for key,value in users.items():
            if debug: print(key+"||||"+value)
            if (int(current_time())-int(value)) > 5:
                if debug: print(key+"is timed out")
                users.pop(key)
                break
        if debug: print("time -",current_time())
        if debug: print("watchers -",watchers_last_seen.keys(),"::::: users - ",users.keys())
        sleep(10)

def run_flask_server():
    api.run(host="0.0.0.0", port=5622)

def main():
    t1 = threading.Thread(target=run_ws_server)
    t2 = threading.Thread(target=run_flask_server)
    t3 = threading.Thread(target=timeout_task)

    t1.start()
    t2.start()
    t3.start()

    t1.join()
    t2.join()
    t3.join()
 
if __name__ == "__main__":
    main()
