// Production/dev entrypoint: starts the listener. Kept separate from
// src/app.ts so tests can build+inject without binding a real port.
// Local-only: binds 127.0.0.1 (CLAUDE.md / design spec — no internet exposure).

import path from "node:path";
import { fileURLToPath } from "node:url";
import dotenv from "dotenv";
import { buildApp } from "./app.js";
import { maybeDailyBackup } from "./backup.js";
import { maybeDailyUpdateCheck } from "./updates.js";

// Load the repo-root .env regardless of the process's cwd (npm workspace
// scripts run with cwd = the workspace directory, i.e. server/).
const serverDir = path.dirname(fileURLToPath(import.meta.url));
dotenv.config({ path: path.resolve(serverDir, "../../.env"), quiet: true });

const HOST = "127.0.0.1";
const isProduction = process.env.NODE_ENV === "production";
const PORT = process.env.PORT ? Number(process.env.PORT) : isProduction ? 3000 : 3001;

const app = await buildApp();

app
  .listen({ port: PORT, host: HOST })
  .then(() => {
    console.log(`server listening on http://${HOST}:${PORT}`);
    // Non-blocking: a backup failure (missing pg_dump, unreachable DB, full
    // disk...) must never crash or delay the server. maybeDailyBackup()
    // already catches and logs its own errors; this .catch is a last-resort
    // safety net against something unexpected escaping it anyway.
    void maybeDailyBackup().catch((err: unknown) => {
      console.error("daily backup check failed:", err);
    });
    // Same non-blocking, never-crash-the-server posture as the backup check
    // above: an update-feed failure (missing UPDATE_FEED_URL, unreachable
    // site, malformed response) must never delay or take down the server.
    // maybeDailyUpdateCheck() already catches and logs its own errors; this
    // .catch is a last-resort safety net against something unexpected
    // escaping it anyway.
    void maybeDailyUpdateCheck().catch((err: unknown) => {
      console.error("daily update check failed:", err);
    });
  })
  .catch((err: unknown) => {
    console.error(err);
    process.exit(1);
  });
