from yasi_applets.install import bp
from flask import Flask, request, session, redirect, \
     url_for, render_template, flash, Blueprint, jsonify
from flask import current_app

import subprocess
import threading
import os

status = {
    "status": "idle",  # idle | running | finished
    "output": "",
    "exit_code": None,
    "lines": []
}


@bp.route('/install',methods=['GET', 'POST', 'PUT'])
def install_index():
    """
    The page you'd get if you access the root of
    this app in a browser.
    """
    install_start()
    return render_template('install.html', hide_menu = True, hide_help = True, hide_close = True)


@bp.route('/install-start',methods=['GET', 'POST', 'PUT'])
def install_start():
    """
    Trigger the installation process
    """
    print("The installation process is starting!... in theory at least")
    if status["status"] == "running":
        return jsonify({"status": "already running"}), 409  # Conflict
    threading.Thread(target=run_script).start()
    return jsonify({"status": "started"})
    print("did it finish?")


def run_script():
    global status
    status["status"] = "running"

    process = subprocess.Popen(
        ["dmm-perform-recipe", "/etc/yasi/final-install.yaml"],
        stdout = subprocess.PIPE,
        stderr = subprocess.STDOUT,
        text = True)

    lines = []
    for line in iter(process.stdout.readline,''):
        #lines.append(line.strip())
        #status["output"] = "\n".join(lines)
        status["lines"].append(line.strip())

    process.wait()
    status["status"] = 'finished'
    status["exit_code"] = process.returncode

    print(lines)
    print("status:", status["status"], "code:", status["exit_code"])


@bp.route('/install/status', methods=['GET', 'POST'])
def install_status():
    """
    Update on the status of the installation process.
    """

    # Keep track of the last line posted, so that we can include
    # any new lines not provided to the UI yet
    last_line = int(request.args.get("last_line", 0))
    new_lines = status["lines"][last_line:]

    #if not new_lines and status["status"] == "finished":
    if status["status"] == "finished":
        return ""  # Empty response = HTMX will stop polling

    lines_html = ""
    if not 'percentage' in status:
        status['percentage'] = "0" 
    for i, line in enumerate(new_lines, start=last_line + 1):
        lines_html += f'<div>{line}</div>'
        if "Running task: " in line:
            status['status_label'] = line.split("Running task:")[1]
            if "initialize_disk" in line:
                status['percentage'] = "2"
            if "create_partitions" in line:
                status['percentage'] = "20"
            if "mount_rootfs" in line:
                status['percentage'] = "25"
            if "install_debian" in line:
                status['percentage'] = "30"
            if "apt_setup" in line:
                status['percentage'] = "45"
            if "setup_bind_mounts" in line:
                status['percentage'] = "50"
            if "users" in line:
                status['percentage'] = "60"
            if "popcon" in line:
                status['percentage'] = "65"
            if "install_desktop_environment" in line:
                status['percentage'] = "65"
            if "install_linux" in line:
                status['percentage'] = "75"
            if "setup_grub" in line:
                status['percentage'] = "85"
            if "unmount_filesystems" in line:
                status['percentage'] = "100"
                status["status"] = "finished"

    return {
        "output": status['output'],
        "status": status['status'],
        "lines": lines_html,
        "percentage": status['percentage'],
        "last_line": f'<input type="hidden" id="last-line" name="last_line" value="{last_line + len(new_lines)}">'
    }


@bp.route('/install/status/percentagediv', methods=['GET'])
def install_percentage_div():
    """
    Provides a new div with the percentage of whatever is happening right now.
    """
    install_status()
    if not 'percentage' in status:
        status['percentage'] = "0" 
    else:
        return '<div class="progress-bar" id="percentagediv" style="width: ' + status['percentage'] + '%;"> </div>'


@bp.route('/install/status/percentage', methods=['GET'])
def install_percentage():
    """
    Provides the percentage of whatever is happening right now.
    """
    install_status()
    if not 'percentage' in status:
        status['percentage'] = "0" 
    return status['percentage']


@bp.route('/install/status/status_label', methods=['GET'])
def install_status_label():
    """
    Provides the status label displayed beneath the progress bar.
    """
    install_status()
    if not 'status_label' in status:
        status['status_label'] = "Initializing..." 
        if status["status"] == "finished": 
            status['status_label'] == "All done!"
    return status['status_label']


@bp.route('/install/get-slide', methods=['GET'])
def install_get_slide():
    """
    Return slide from installer slideshow.
    """
    if 'status_label' in status:
        if status['percentage'] == "100":
            return render_template("slide_complete.html")
        else:
            return render_template("slide_installing.html")



@bp.route('/install/complete', methods=['GET', 'POST'])
def install_complete():
    """
    Installation complete page.
    """
    return render_template("complete.html")


@bp.route('/install/reboot', methods=['GET', 'POST'])
def install_reboot():
    """
    Perform a sync and trigger a hard reboot.
    """
    os.system("sync")
    os.system("echo b > /proc/sysrq-trigger")


@bp.route('/install/cancel', methods=["POST"])
def install_cancel():
    """
    Cancel the installation process.
    """
    if status["status"] != "running" or not status["process"]:
        return Response("No running script", status=400)
    process["process"].terminate()
    process["status"] = "cancelled"
    process["exit_code"] = -1
    return Response("Cancelled", status=200)


@bp.route('/settings',methods=['GET', 'POST', 'PUT'])
def settings():
    """
    Manage settings for the installation module.
    """
    print("Settings")
