"""DWG-to-DXF conversion microservice via ODA File Converter."""

import glob
import os
import shutil
import subprocess
import tempfile
import uuid

from flask import Flask, request, send_file, jsonify

app = Flask(__name__)

MAX_FILE_SIZE = 100 * 1024 * 1024  # 100 MB

# ODA File Converter — try common install paths
ODA_BIN = "/usr/local/bin/ODAFileConverter"
for _p in ["/usr/local/bin/ODAFileConverter", "/usr/bin/ODAFileConverter",
           "/opt/ODAFileConverter/ODAFileConverter",
           "/opt/oda-file-converter/ODAFileConverter"]:
    if os.path.isfile(_p):
        ODA_BIN = _p
        break


@app.route("/health", methods=["GET"])
def health():
    """Health check — verifies ODA File Converter is installed."""
    if os.path.isfile(ODA_BIN) and os.access(ODA_BIN, os.X_OK):
        return jsonify({"status": "ok", "converter": "ODAFileConverter"}), 200
    return jsonify({"status": "error", "detail": "ODAFileConverter not found"}), 503


@app.route("/convert", methods=["POST"])
def convert():
    """Accept a DWG file via multipart upload, return DXF."""
    if "file" not in request.files:
        return jsonify({"error": "Missing 'file' field in upload."}), 400

    uploaded = request.files["file"]
    original_name = uploaded.filename or "input.dwg"

    if not original_name.lower().endswith(".dwg"):
        return jsonify({"error": "File must have .dwg extension."}), 400

    safe_name = "".join(
        c if c.isalnum() or c in "._-" else "_" for c in original_name
    )

    work_dir = os.path.join(tempfile.gettempdir(), f"dwg-{uuid.uuid4().hex}")
    input_dir = os.path.join(work_dir, "in")
    output_dir = os.path.join(work_dir, "out")
    os.makedirs(input_dir, exist_ok=True)
    os.makedirs(output_dir, exist_ok=True)

    input_path = os.path.join(input_dir, safe_name)

    try:
        uploaded.save(input_path)

        file_size = os.path.getsize(input_path)
        if file_size > MAX_FILE_SIZE:
            return jsonify({"error": f"File too large ({file_size} bytes)."}), 413

        # ODA File Converter: input_dir output_dir version type recurse audit
        # ACAD2018 = output DXF version, DXF = output format, 0 = no recurse, 1 = audit
        result = subprocess.run(
            [
                "xvfb-run", "--auto-servernum", "--server-args=-screen 0 1x1x24",
                ODA_BIN, input_dir, output_dir, "ACAD2018", "DXF", "0", "1",
            ],
            capture_output=True,
            timeout=120,
        )

        # Find the output DXF file
        dxf_files = glob.glob(os.path.join(output_dir, "*.dxf"))
        if not dxf_files:
            stderr = result.stderr.decode("utf-8", errors="replace")
            stdout = result.stdout.decode("utf-8", errors="replace")
            detail = stderr or stdout or "No output file produced"
            return jsonify({"error": f"Conversion failed: {detail}"}), 500

        dxf_path = dxf_files[0]
        dxf_name = safe_name.rsplit(".", 1)[0] + ".dxf"

        return send_file(
            dxf_path,
            mimetype="application/dxf",
            as_attachment=True,
            download_name=dxf_name,
        )

    except subprocess.TimeoutExpired:
        return jsonify({"error": "Conversion timed out (120s limit)."}), 504

    except Exception as e:
        return jsonify({"error": f"Unexpected error: {str(e)}"}), 500

    finally:
        shutil.rmtree(work_dir, ignore_errors=True)


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5001)
