#!/bin/python3

import subprocess 
import time
import psutil

NOTEBOOK_DIR = "~/jupyter-notebooks/"
PORT = "8988"

def isOtherProcessRunning():
    process_count = 0
    for proc in psutil.process_iter():
       try:
           pinfo = proc.as_dict(attrs=['pid', 'name', 'create_time'])
           if "jupyter-calc" in pinfo['name'].lower():
               process_count += 1
       except (psutil.NoSuchProcess, psutil.AccessDenied , psutil.ZombieProcess) :
           pass
    return process_count > 1

def getNotebookPort(line):
    url = line.split(" :: ")[0]
    return url.split("localhost:")[1].split("/")[0]

def getNotebookToken(line):
    url = line.split(" :: ")[0]
    return url.split("token=")[1]


def isNotebookRunning():
    answer = subprocess.check_output("jupyter notebook list", shell=True)
    lines = answer.decode("utf-8").split("\n")
    if lines[0] != "Currently running servers:":
        raise Exception("Invalid jupyter status message")

    for i in range(1, len(lines) -1):
        if getNotebookPort(lines[i]) == PORT:
            return getNotebookToken(lines[i]) 
    return None 

if __name__ == "__main__":
    try:
        if not isNotebookRunning():
            print("No notebook instance running. Starting it...")
            subprocess.Popen(f"jupyter notebook --notebook-dir={NOTEBOOK_DIR} --port={PORT} --no-browser", shell=True)
        else:
            print("Notebook instance already running.")

        max_wait_seconds = 3 
        delta_t_seconds = 0.1

        current_wait_seconds = 0

        token = ""
        while True:
            token = isNotebookRunning()
            if token:
                break

            time.sleep(delta_t_seconds)
            current_wait_seconds += delta_t_seconds
            if current_wait_seconds >= max_wait_seconds:
                raise Exception(f"Maximum wait time of {max_wait_seconds} exceeded!")

        subprocess.call(f"cp {NOTEBOOK_DIR}calculator_template.ipynb {NOTEBOOK_DIR}calculator.ipynb", shell=True)

        # url = f"http://localhost:{PORT}/notebooks/calculator.ipynb?token={token}"
        url = f"http://localhost:{PORT}/?token={token}"

        subprocess.call(f"$BROWSER '{url}'", shell=True)

    finally:
        # TODO: not reliably working
        if not isOtherProcessRunning():
            try:
                subprocess.run(f"jupyter notebook stop {PORT}", shell=True)
            except Exception:
                pass
