#!/usr/bin/env python
import websocket
import ssl
import rel
import os
import sys
import queue
from event_scheduler import EventScheduler
from termcolor import colored

"""
Template for work with a remote WebSocket server.

Dependencies:
    pip3 install websocket-client rel event-scheduler termcolor 
"""

# Constants
WS_VERBOSE_MODE = False
WS_URL = "wss://ws.postman-echo.com/raw"
HANDSHAKE_CUSTOM_HTTP_HEADERS = {"X-Test": 123, "X-Test2": "ABC"}
HANDSHAKE_CUSTOM_HTTP_COOKIES = "JSESSIONID=azerty; UserId=ABC;"
HANDSHAKE_CUSTOM_ORIGIN_HEADER = "http://righettod.eu"
PROXY_HOST = None  # "127.0.0.1"
PROXY_PORT = None  # 8080
MESSAGE_FILE = "ws-msg.txt"
MESSAGE_FILE_CHECK_INTERVAL_IN_SECONDS = 10
DATA_QUEUE = queue.Queue()
DATA_QUEUE.put(0)


def sendmsg(client):
    try:
        if not os.path.exists(MESSAGE_FILE):
            print(colored(f"[!] File '{MESSAGE_FILE}' not found!", "yellow"))
            client.send("-")
        else:
            last_modified = os.path.getmtime(MESSAGE_FILE)
            if last_modified != DATA_QUEUE.get():
                with open(MESSAGE_FILE, mode="r", encoding="utf-8") as f:
                    msg = f.read()
                if msg == "exit":
                    print(colored(f"[i] Type CTRL+C to finalize the exit.", "cyan"))
                    client.close()
                    sys.exit(0)
                client.send(msg)
                print(colored(f"[>] Message sent:", "yellow"))
                print(msg)
                DATA_QUEUE.put(last_modified)
            else:
                print(colored("[>] Dummy keep alive message sent.", "yellow"))
                client.send("-")  # Keep alive
    except Exception as e:
        print(colored(f"[!] Exception: {str(e)}", "red"))


def on_message(client, message):
    print(colored("[<] Message received:", "yellow"))
    print(message)


def on_error(client, error):
    print(colored("[X] Error received:", "red"))
    print(error)


def on_close(client, close_status_code, close_msg):
    print(colored(f"[!] Connection closed => Code: {close_status_code} / Reason: {close_msg}.", "yellow"))


def on_open(client):
    print(colored(f"[V] Connected to {WS_URL}.", "green"))


if __name__ == "__main__":
    print(colored(f"[i] Send 'exit' message to quit. Message file '{MESSAGE_FILE}' checked every {MESSAGE_FILE_CHECK_INTERVAL_IN_SECONDS} seconds for update.", "cyan"))
    websocket.enableTrace(WS_VERBOSE_MODE)
    client = websocket.WebSocketApp(WS_URL, on_message=on_message, on_error=on_error, on_close=on_close, on_open=on_open, header=HANDSHAKE_CUSTOM_HTTP_HEADERS, cookie=HANDSHAKE_CUSTOM_HTTP_COOKIES)
    event_scheduler = EventScheduler()
    event_scheduler.start()
    event_scheduler.enter_recurring(MESSAGE_FILE_CHECK_INTERVAL_IN_SECONDS, 0, sendmsg, (client,))
    if PROXY_HOST is not None and PROXY_PORT is not None:
        client.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE}, origin=HANDSHAKE_CUSTOM_ORIGIN_HEADER, http_proxy_host=PROXY_HOST, http_proxy_port=PROXY_PORT, dispatcher=rel)
    else:
        client.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE}, origin=HANDSHAKE_CUSTOM_ORIGIN_HEADER, dispatcher=rel)
    rel.signal(2, rel.abort)  # Keyboard Interrupt
    rel.dispatch()
