from pathlib import Path
import os

from flask import redirect, url_for, Blueprint, send_file, render_template
from werkzeug.utils import secure_filename
import redis  # dependency via rq
import uuid

import config
from helpers.flask_response import basic_msg, basic_msg_html
from helpers.rq_helper import REDIS_QUEUE, rq_job_failed, rq_job_finalized
from helpers.custom_logging import FlashLog
from helpers.file_root import relative_path
from pwndoc_api import download_report, get_docx_filepath

bp = Blueprint('api_pwndoc_audit', __name__, template_folder='templates')


@bp.route("/report_download/<audit_id>", methods=["GET"])
def report_download(audit_id: str):
    docx_filename = f"report_{audit_id}_{uuid.uuid4()}.docx"

    if config.RQ_DISABLED:
        download_report(audit_id, docx_filename)
        return redirect(url_for("api_pwndoc_audit.report_progress", docx_filename=docx_filename))

    try:
        enqueue_result = REDIS_QUEUE.enqueue(
            download_report, args=(audit_id, docx_filename,),
            job_timeout=config.RQ_JOB_TIMEOUT, ttl='1d', result_ttl=7*24*60*60, job_id=docx_filename
        )
    except redis.exceptions.ConnectionError as e:
        FlashLog.log_and_flash_with_level(f"Failed to connect to Redis - is the container running? ({e})", "error")

    return redirect(url_for("api_pwndoc_audit.report_progress", docx_filename=docx_filename))


@bp.route("/report_progress/<docx_filename>", methods=["GET"])
def report_progress(docx_filename: str):
    docx_filename = secure_filename(docx_filename)
    result_filepath = get_docx_filepath(docx_filename)

    def _success_response():
        return basic_msg_html(f'Report file is ready. <a href="{url_for("api_pwndoc_audit.report_file", docx_filename=docx_filename)}">Download docx report</a>')

    does_file_exist = Path(result_filepath).is_file()

    if config.RQ_DISABLED:
        if does_file_exist:
            return _success_response()
        FlashLog.error("The download of report failed.")
        return basic_msg("")

    if rq_job_finalized(docx_filename) is False:
        return basic_msg_html("""
            This pwndoc docx result doesn't not exist yet. This page will autorefresh until it does.
            <script> setTimeout(function () { location.reload(1); }, 2000); </script>
            """)

    if rq_job_failed(docx_filename):
        FlashLog.error("The download of report in background failed.")
        return basic_msg("")

    if not does_file_exist:
        FlashLog.flash_loguru_msg("The download of report in background is no longer running, but no result file was produced. This likely indicates error.", "danger")
        return basic_msg("")

    return _success_response()


@bp.route("/report_file/<docx_filename>", methods=["GET"])
def report_file(docx_filename: str):
    result_filepath = get_docx_filepath(secure_filename(docx_filename))
    # todo: maybe somehow delete the file after download?
    return send_file(result_filepath, download_name=os.path.basename(result_filepath), as_attachment=True)

