"""OpenClaw Adapter - sprava worker subprocessu."""
import json
import os
import signal
import subprocess
import time
import uuid
from datetime import datetime
from pathlib import Path


class OpenClawAdapter:
    def __init__(self, base_dir):
        self.base_dir = Path(base_dir).resolve()
        self.runs_dir = self.base_dir / "data-lab" / "openclaw_runs"
        self.runs_dir.mkdir(parents=True, exist_ok=True)
        self.running = {}

    def start(self, task_id, worktree_path, description, max_steps=10):
        run_id = str(uuid.uuid4())[:8]
        output_file = self.runs_dir / f"{run_id}.json"
        log_file = self.runs_dir / f"{run_id}.log"
        worker_script = self.base_dir / "core" / "openclaw_worker.py"

        cmd = [
            "python3", str(worker_script),
            "--task-id", task_id,
            "--worktree", worktree_path,
            "--description", description,
            "--max-steps", str(max_steps),
            "--output", str(output_file),
        ]

        env = os.environ.copy()
        env.setdefault("LITELLM_MASTER_KEY", "sk-dummy")

        log_f = open(log_file, "w")
        proc = subprocess.Popen(
            cmd, cwd=str(self.base_dir), env=env,
            stdout=log_f, stderr=subprocess.STDOUT,
            start_new_session=True,
        )

        info = {
            "run_id": run_id, "task_id": task_id, "worktree": worktree_path,
            "description": description, "output_file": str(output_file),
            "log_file": str(log_file), "started_at": datetime.utcnow().isoformat(),
            "pid": proc.pid, "proc": proc, "log_f": log_f,
        }
        self.running[run_id] = info
        return {"run_id": run_id, "status": "running", "pid": proc.pid}

    def status(self, run_id):
        info = self.running.get(run_id)
        if not info:
            output_file = self.runs_dir / f"{run_id}.json"
            if output_file.exists():
                try:
                    return {"run_id": run_id, "status": "finished",
                            "result": json.loads(output_file.read_text())}
                except Exception as e:
                    return {"run_id": run_id, "status": "error", "error": str(e)}
            return None
        proc = info["proc"]
        rc = proc.poll()
        if rc is None:
            return {"run_id": run_id, "status": "running", "pid": info["pid"]}
        try:
            info["log_f"].close()
        except Exception:
            pass
        output_file = Path(info["output_file"])
        result = None
        if output_file.exists():
            try:
                result = json.loads(output_file.read_text())
            except Exception:
                result = None
        return {
            "run_id": run_id,
            "status": "finished" if rc == 0 else "failed",
            "exit_code": rc, "task_id": info["task_id"], "result": result,
        }

    def stop(self, run_id):
        info = self.running.get(run_id)
        if not info:
            return {"stopped": False, "error": "Run nenalezen"}
        proc = info["proc"]
        if proc.poll() is not None:
            return {"stopped": False, "error": "Jiz ukoncen"}
        try:
            os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
        except Exception:
            proc.terminate()
        time.sleep(0.5)
        if proc.poll() is None:
            proc.kill()
        try:
            info["log_f"].close()
        except Exception:
            pass
        return {"stopped": True, "run_id": run_id}

    def list_runs(self, task_id=None, limit=50):
        items = []
        files = sorted(self.runs_dir.glob("*.json"), key=lambda x: x.stat().st_mtime, reverse=True)
        for f in files:
            try:
                data = json.loads(f.read_text())
                if task_id and data.get("task_id") != task_id:
                    continue
                items.append({
                    "run_id": f.stem,
                    "task_id": data.get("task_id"),
                    "success": data.get("success"),
                    "summary": data.get("summary", ""),
                    "steps": data.get("steps", 0),
                })
                if len(items) >= limit:
                    break
            except Exception:
                continue
        return items

    def get_result(self, run_id):
        output_file = self.runs_dir / f"{run_id}.json"
        if not output_file.exists():
            return None
        return json.loads(output_file.read_text())

    def get_log(self, run_id, tail=100):
        log_file = self.runs_dir / f"{run_id}.log"
        if not log_file.exists():
            return ""
        lines = log_file.read_text(errors="replace").splitlines()
        return "\n".join(lines[-tail:])
