#!/usr/bin/env python3
"""odysseus-tasks — shell wrapper for the scheduled-tasks feature.

    odysseus-tasks list [--status active|paused|completed] [--limit N]
    odysseus-tasks show TASK_ID
    odysseus-tasks pause TASK_ID
    odysseus-tasks resume TASK_ID
    odysseus-tasks runs [--task TASK_ID] [--limit N]
"""

from __future__ import annotations
import sys
import os, sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "_lib"))
from cli import quiet_logs, emit, fail, common_parser, run, REPO_ROOT as _REPO_ROOT
quiet_logs()

import argparse, json, logging, os, sys
from pathlib import Path

try:
    from core.database import SessionLocal, ScheduledTask, TaskRun
    quiet_logs()
except ModuleNotFoundError as e:
    sys.stderr.write(f"error: {e}\nhint: run from repo root with venv active.\n")
    sys.exit(2)


def _preview_text(value, limit: int = 200) -> str:
    text = value if isinstance(value, str) else ""
    return text[:limit] + ("…" if len(text) > limit else "")


def _serialize_task(t: "ScheduledTask") -> dict:
    return {
        "id": t.id,
        "name": t.name,
        "task_type": t.task_type,
        "action": t.action,
        "prompt": _preview_text(t.prompt),
        "schedule": t.schedule,
        "scheduled_time": t.scheduled_time,
        "next_run": t.next_run.isoformat() if t.next_run else "",
        "last_run": t.last_run.isoformat() if t.last_run else "",
        "status": t.status,
        "model": t.model,
        "run_count": t.run_count or 0,
        "cron_expression": t.cron_expression or "",
    }


def _serialize_run(r: "TaskRun") -> dict:
    return {
        "id": r.id,
        "task_id": r.task_id,
        "started_at": r.started_at.isoformat() if r.started_at else "",
        "completed_at": r.completed_at.isoformat() if r.completed_at else "",
        "status": r.status,
        "output_preview": _preview_text(getattr(r, "output", "")),
    }


def cmd_list(args):
    db = SessionLocal()
    try:
        q = db.query(ScheduledTask)
        if args.status:
            q = q.filter(ScheduledTask.status == args.status)
        q = q.order_by(ScheduledTask.next_run.asc().nulls_last()).limit(args.limit)
        emit([_serialize_task(t) for t in q.all()], args)
    finally:
        db.close()


def cmd_show(args):
    db = SessionLocal()
    try:
        t = db.get(ScheduledTask, args.id)
        if not t:
            fail(f"no task with id {args.id!r}")
        out = _serialize_task(t)
        # Include full prompt + recent runs for detail view
        out["prompt_full"] = t.prompt or ""
        out["endpoint_url"] = t.endpoint_url or ""
        out["session_id"] = t.session_id or ""
        out["webhook_token"] = "***" if t.webhook_token else ""
        runs = db.query(TaskRun).filter(TaskRun.task_id == t.id).order_by(
            TaskRun.started_at.desc()
        ).limit(5).all()
        out["recent_runs"] = [_serialize_run(r) for r in runs]
        emit(out, args)
    finally:
        db.close()


def cmd_pause(args):
    _set_status(args, "paused")


def cmd_resume(args):
    _set_status(args, "active")


def _set_status(args, new_status: str):
    db = SessionLocal()
    try:
        t = db.get(ScheduledTask, args.id)
        if not t:
            fail(f"no task with id {args.id!r}")
        t.status = new_status
        db.commit()
        db.refresh(t)
        emit({"ok": True, "id": t.id, "status": t.status}, args)
    finally:
        db.close()


def cmd_runs(args):
    db = SessionLocal()
    try:
        q = db.query(TaskRun)
        if args.task:
            q = q.filter(TaskRun.task_id == args.task)
        q = q.order_by(TaskRun.started_at.desc()).limit(args.limit)
        emit([_serialize_run(r) for r in q.all()], args)
    finally:
        db.close()


def _build_parser():
    common = argparse.ArgumentParser(add_help=False)
    common.add_argument("--pretty", action="store_true")

    p = argparse.ArgumentParser(prog="odysseus-tasks", parents=[common])
    sub = p.add_subparsers(dest="cmd", required=True)

    pl = sub.add_parser("list", parents=[common])
    pl.add_argument("--status", choices=["active", "paused", "completed"])
    pl.add_argument("--limit", type=int, default=50)
    pl.set_defaults(func=cmd_list)

    psh = sub.add_parser("show", parents=[common])
    psh.add_argument("id")
    psh.set_defaults(func=cmd_show)

    pp = sub.add_parser("pause", parents=[common])
    pp.add_argument("id")
    pp.set_defaults(func=cmd_pause)

    pr = sub.add_parser("resume", parents=[common])
    pr.add_argument("id")
    pr.set_defaults(func=cmd_resume)

    prn = sub.add_parser("runs", parents=[common])
    prn.add_argument("--task", help="filter by task id")
    prn.add_argument("--limit", type=int, default=20)
    prn.set_defaults(func=cmd_runs)

    return p


if __name__ == "__main__":
    sys.exit(run(_build_parser()))
