#!/usr/bin/env python3
"""
Serveur HTTP minimal pour déclencher hermes-auto-improve depuis n8n.
Écoute sur 0.0.0.0:9095.

Les POST /trigger* retournent immédiatement {"started": true}.
Le script tourne en background thread.
Polling du résultat via GET /status.

POST /trigger           → run standard (MAX_FILES fichiers)
POST /trigger/subdir    → body JSON {"subdir": "ia"}
POST /trigger/dry-run   → analyse sans commit/push
POST /trigger/daily-pr  → crée PR GitHub + résumé journalier
GET  /status            → dernier résultat + état running
GET  /health            → {"ok": true}
"""

import json
import subprocess
import threading
from datetime import datetime
from http.server import BaseHTTPRequestHandler, HTTPServer
from pathlib import Path

SCRIPT     = "/usr/local/bin/hermes-auto-improve"
STATE_FILE = Path("/var/lib/hermes-auto-improve/state.json")
LOG_FILE   = Path("/var/log/hermes-auto-improve.log")

_lock        = threading.Lock()
_running     = False
_last_result = None


def _extract_last_json(text: str):
    """Find the outermost JSON object at the end of mixed text+JSON output."""
    end = text.rfind("}")
    if end < 0:
        return None
    depth = 0
    for i in range(end, -1, -1):
        if text[i] == "}":
            depth += 1
        elif text[i] == "{":
            depth -= 1
            if depth == 0:
                try:
                    return json.loads(text[i:end + 1])
                except json.JSONDecodeError:
                    return None
    return None


def run_script(extra_args: list = None):
    global _running, _last_result
    with _lock:
        if _running:
            return
        _running = True

    try:
        cmd = [SCRIPT] + (extra_args or [])
        LOG_FILE.parent.mkdir(parents=True, exist_ok=True)
        with open(LOG_FILE, "a") as log:
            log.write(f"\n=== {datetime.now().isoformat()} — {' '.join(cmd)} ===\n")
            result = subprocess.run(
                cmd, capture_output=True, text=True, timeout=7200
            )
            log.write(result.stdout)
            if result.stderr:
                log.write(f"STDERR: {result.stderr}")

        out = result.stdout
        _last_result = _extract_last_json(out) or {"error": "no_json", "stdout": out[-500:]}

    except subprocess.TimeoutExpired:
        _last_result = {"error": "timeout"}
    except Exception as e:
        _last_result = {"error": str(e)}
    finally:
        _running = False


def trigger_async(extra_args: list = None) -> dict:
    with _lock:
        if _running:
            return {"started": False, "error": "already_running"}
    t = threading.Thread(target=run_script, args=(extra_args,), daemon=True)
    t.start()
    return {"started": True, "running": True}


class Handler(BaseHTTPRequestHandler):
    def log_message(self, fmt, *args):
        pass

    def send_json(self, code: int, data: dict):
        body = json.dumps(data, ensure_ascii=False, indent=2).encode()
        self.send_response(code)
        self.send_header("Content-Type", "application/json")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

    def do_GET(self):
        if self.path == "/health":
            self.send_json(200, {"ok": True, "running": _running})
        elif self.path == "/status":
            state = json.loads(STATE_FILE.read_text()) if STATE_FILE.exists() else None
            self.send_json(200, {"state": state, "last_result": _last_result, "running": _running})
        else:
            self.send_json(404, {"error": "not_found"})

    def do_POST(self):
        length = int(self.headers.get("Content-Length", 0))
        body   = json.loads(self.rfile.read(length)) if length > 0 else {}

        if self.path == "/trigger":
            self.send_json(200, trigger_async())

        elif self.path == "/trigger/all":
            self.send_json(200, trigger_async(["--all"]))

        elif self.path == "/trigger/subdir":
            subdir = body.get("subdir")
            if not subdir:
                self.send_json(400, {"error": "missing 'subdir' in body"})
                return
            self.send_json(200, trigger_async(["--subdir", subdir]))

        elif self.path == "/trigger/dry-run":
            self.send_json(200, trigger_async(["--dry-run"]))

        elif self.path == "/trigger/daily-pr":
            self.send_json(200, trigger_async(["--daily-pr"]))

        elif self.path == "/trigger/reset":
            self.send_json(200, trigger_async(["--reset"]))

        else:
            self.send_json(404, {"error": "not_found"})


if __name__ == "__main__":
    server = HTTPServer(("0.0.0.0", 9095), Handler)
    print("hermes-auto-improve trigger server — port 9095", flush=True)
    server.serve_forever()
