# Filename: /home/user/app/app.py
# Version: 1691068773 (Unix timestamp at creation moment)

import os
import subprocess

# Definir el archivo de log antes de instalar las bibliotecas
log_file = "/home/user/app/app.log"

# Instalar las bibliotecas necesarias
def install_packages():
    # Instalar los paquetes necesarios
    with open(log_file, "a") as f:
        f.write("===== Installing Packages =====\n")
        subprocess.run(['pip3', 'install', 'jupyterlab', 'flask', 'gradio', 'psutil', 'requests'], check=True, stdout=f, stderr=f)

install_packages()

# Ahora importar las bibliotecas necesarias
from flask import Flask, redirect, request, Response
import gradio as gr
import psutil
import requests

app = Flask(__name__)

def is_jupyter_running():
    # Verificar si JupyterLab ya está en ejecución
    for process in psutil.process_iter(['pid', 'name']):
        if 'jupyter-lab' in process.info['name']:
            return True
    return False

def configure_jupyter():
    # Generar la configuración de Jupyter
    jupyter_config_dir = os.path.expanduser('~/.jupyter')
    os.makedirs(jupyter_config_dir, exist_ok=True)
    
    config_file = os.path.join(jupyter_config_dir, 'jupyter_lab_config.py')
    jupyter_password = os.environ.get('JUPYPASS', '')
    password_config = f"c.ServerApp.password = u'{jupyter_password}'" if jupyter_password else ''
    
    with open(config_file, 'w') as f:
        f.write(f"""
c.ServerApp.ip = '0.0.0.0'
c.ServerApp.port = 8898
c.ServerApp.open_browser = False
{password_config}
c.ServerApp.root_dir = '/home/user/app'
c.ServerApp.terminado_settings = {{'shell_command': ['bash']}}
c.ServerApp.allow_root = True
        """)

def start_jupyter():
    # Iniciar JupyterLab en el puerto 8898 con autoreload si no está en ejecución
    if not is_jupyter_running():
        with open(log_file, "a") as f:
            subprocess.Popen(['jupyter-lab', '--port', '8898', '--autoreload'], stdout=f, stderr=f)

@app.route('/')
def home():
    def greet(name):
        return f"Hello {name}!"
    
    with gr.Blocks() as demo:
        gr.Interface(fn=greet, inputs="text", outputs="text")
    
    return demo.launch(inline=True)

@app.route('/jupy')
def jupy():
    # Proxy inverso para JupyterLab
    jupyter_url = "http://localhost:8898"
    resp = requests.request(
        method=request.method,
        url=jupyter_url + request.path,
        headers={key: value for key, value in request.headers if key != 'Host'},
        data=request.get_data(),
        cookies=request.cookies,
        allow_redirects=False)
    
    excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
    headers = [(name, value) for name, value in resp.raw.headers.items() if name.lower() not in excluded_headers]

    response = Response(resp.content, resp.status_code, headers)
    return response

if __name__ == "__main__":
    with open(log_file, "a") as f:
        f.write("===== Application Startup at {0} =====\n".format(subprocess.run(['date'], capture_output=True, text=True).stdout))
    
    configure_jupyter()
    start_jupyter()
    
    app.run(host='0.0.0.0', port=7860, debug=False)