#!/usr/bin/env node
/**
 * Tiny HTTP agent on the dashboards VPS.
 * Super Admin → Nest API → POST here → runs ssl-sync.sh in the background.
 *
 * Env (/etc/meshkee/ssl-sync-agent.env):
 *   SSL_SYNC_AGENT_TOKEN=...
 *   SSL_SYNC_SCRIPT=/opt/meshkee/dashboards/deploy/ssl-sync.sh
 *   PORT=9051
 *   BIND=0.0.0.0
 */
import { createServer } from 'node:http'
import { spawn } from 'node:child_process'
import { accessSync, constants } from 'node:fs'

const TOKEN = (process.env.SSL_SYNC_AGENT_TOKEN || '').trim()
const SCRIPT =
  (process.env.SSL_SYNC_SCRIPT || '/opt/meshkee/dashboards/deploy/ssl-sync.sh').trim()
const PORT = Number(process.env.PORT || 9051)
const BIND = (process.env.BIND || '0.0.0.0').trim()

if (!TOKEN) {
  console.error('SSL_SYNC_AGENT_TOKEN is required')
  process.exit(1)
}

try {
  accessSync(SCRIPT, constants.X_OK)
} catch {
  console.error(`SSL sync script missing or not executable: ${SCRIPT}`)
  process.exit(1)
}

let running = false

function json(res, status, body) {
  const payload = JSON.stringify(body)
  res.writeHead(status, {
    'Content-Type': 'application/json',
    'Content-Length': Buffer.byteLength(payload),
  })
  res.end(payload)
}

function startSync() {
  running = true
  const child = spawn(SCRIPT, [], {
    detached: true,
    stdio: 'ignore',
    env: process.env,
  })
  child.on('error', (err) => {
    console.error(`${new Date().toISOString()} spawn error:`, err.message)
    running = false
  })
  child.on('exit', (code, signal) => {
    console.log(
      `${new Date().toISOString()} ssl-sync finished code=${code} signal=${signal ?? ''}`,
    )
    running = false
  })
  child.unref()
}

const server = createServer((req, res) => {
  if (req.method === 'GET' && req.url === '/health') {
    return json(res, 200, { ok: true, running })
  }

  if (req.method !== 'POST' || req.url !== '/ssl-sync') {
    return json(res, 404, { error: 'not found' })
  }

  const provided = String(req.headers['x-ssl-sync-agent-token'] ?? '').trim()
  if (!provided || provided !== TOKEN) {
    return json(res, 401, { error: 'unauthorized' })
  }

  if (running) {
    return json(res, 409, { error: 'ssl sync already running' })
  }

  startSync()
  console.log(`${new Date().toISOString()} ssl-sync accepted`)
  return json(res, 202, {
    status: 'accepted',
    message: 'SSL sync started',
  })
})

server.listen(PORT, BIND, () => {
  console.log(`ssl-sync-agent listening on ${BIND}:${PORT}`)
})
