#!/usr/bin/env bun
import { NativeConnection, Worker } from "@temporalio/worker";
import path from "node:path";

import { createTaskTreeActivities } from "../../internal/tasktree/activities.ts";
import { startTaskTreeBackupScheduler } from "../../internal/tasktree/backup.ts";
import { taskTreeRuntime } from "../../internal/tasktree/runtime.ts";

const runtime = taskTreeRuntime({
  ...process.env,
  TASKTREE_BACKUP_WORKTREE: process.env.TASKTREE_BACKUP_WORKTREE ?? ".state/tasktree/backup-repo-worker",
});
if (!runtime.temporalAddress) throw new Error("TASKTREE_TEMPORAL_ADDRESS is required");
await runtime.store.ensureSchema();
const connection = await NativeConnection.connect({ address: runtime.temporalAddress });
const worker = await Worker.create({
  connection,
  namespace: runtime.temporalNamespace,
  taskQueue: runtime.taskQueue,
  workflowsPath: path.resolve(import.meta.dir, "../../internal/tasktree/workflows.ts"),
  activities: createTaskTreeActivities(runtime.store)
});
const healthPort = Number.parseInt(process.env.TASKTREE_WORKER_HEALTH_PORT || "6674", 10);
const backupScheduler = startTaskTreeBackupScheduler(runtime.backup, (result) => {
  process.stdout.write(`${JSON.stringify({ serviceId: "hwlab-tasktree-worker", ...result })}\n`);
});
const health = Bun.serve({
  hostname: process.env.TASKTREE_WORKER_HEALTH_HOST || "0.0.0.0",
  port: healthPort,
  async fetch(request) {
    const pathname = new URL(request.url).pathname;
    if (pathname !== "/health/live" && pathname !== "/health/ready") return Response.json({ ok: false, error: "not_found" }, { status: 404 });
    return Response.json({
      ok: true,
      serviceId: "hwlab-tasktree-worker",
      namespace: runtime.temporalNamespace,
      taskQueue: runtime.taskQueue,
      backup: await runtime.backup.status(),
    });
  }
});

process.stdout.write(`${JSON.stringify({ serviceId: "hwlab-tasktree-worker", status: "started", namespace: runtime.temporalNamespace, taskQueue: runtime.taskQueue })}\n`);
for (const signal of ["SIGINT", "SIGTERM"] as const) process.once(signal, () => worker.shutdown());
try {
  await worker.run();
} finally {
  await backupScheduler.stop();
  health.stop(true);
  await connection.close();
  await runtime.store.close();
  process.stdout.write(`${JSON.stringify({ serviceId: "hwlab-tasktree-worker", status: "stopped" })}\n`);
}
