#!/usr/bin/env node
// Standalone arr upgrade webhook listener.
// Started by start_webhook_listener.sh via `node webhook_listener.js`.
// Lives outside Unraid nginx — no session auth. Secret in URL is the only gate.
//
// Usage: node webhook_listener.js <port> <secret> <scripts_dir>

'use strict';

const http       = require('http');
const { exec }   = require('child_process');
const fs         = require('fs');
const path       = require('path');

const [,, port, secret, scriptsDir] = process.argv;

if (!port || !secret || !scriptsDir) {
    process.stderr.write('Usage: webhook_listener.js <port> <secret> <scripts_dir>\n');
    process.exit(1);
}

const LOG_FILE   = '/var/log/varaverk/upgrade_webhook.log';
const HANDLER    = path.join(scriptsDir, 'Arrs_Stack', 'upgrade_webhook_handler.sh');

function log(msg) {
    const ts = new Date().toTimeString().slice(0, 8);
    const line = `[${ts}] ${msg}\n`;
    fs.appendFile(LOG_FILE, line, () => {});
}

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

const server = http.createServer((req, res) => {
    const url    = new URL(req.url, `http://localhost`);
    const key    = url.searchParams.get('key');

    if (key !== secret) {
        send(res, 403, { ok: false, error: 'Forbidden' });
        return;
    }

    if (req.method !== 'POST') {
        send(res, 405, { ok: false, error: 'POST only' });
        return;
    }

    let body = '';
    req.on('data', chunk => { body += chunk; });
    req.on('end', () => {
        let payload;
        try { payload = JSON.parse(body); }
        catch (_) { send(res, 400, { ok: false, error: 'Invalid JSON' }); return; }

        const event     = payload.eventType ?? '';
        const isUpgrade = payload.isUpgrade ?? false;

        if (event === 'Test') {
            send(res, 200, { ok: true, message: 'Webhook connected — upgrade propagation active' });
            return;
        }

        if (event !== 'Download' || !isUpgrade) {
            send(res, 200, { ok: true, skipped: event });
            return;
        }

        let arrType, itemPath;
        if (payload.series?.path) {
            arrType  = 'sonarr';
            itemPath = payload.series.path;
        } else if (payload.movie?.folderPath) {
            arrType  = 'radarr';
            itemPath = payload.movie.folderPath;
        } else if (payload.artist?.path) {
            arrType  = 'lidarr';
            itemPath = payload.artist.path;
        } else {
            send(res, 400, { ok: false, error: 'Unrecognised payload structure' });
            return;
        }

        if (!itemPath || !itemPath.startsWith('/') || itemPath.includes('..') || /[\x00\n\r]/.test(itemPath)) {
            send(res, 400, { ok: false, error: 'Unsafe path' });
            return;
        }

        log(`Upgrade: ${arrType} — ${path.basename(itemPath)}`);
        send(res, 200, { ok: true, arr: arrType, path: itemPath });

        const cmd = `bash ${JSON.stringify(HANDLER)} ${JSON.stringify(arrType)} ${JSON.stringify(itemPath)}`;
        const out = fs.createWriteStream(LOG_FILE, { flags: 'a' });
        exec(cmd, { stdio: ['ignore', out, out] });
    });
});

server.listen(parseInt(port, 10), '0.0.0.0', () => {
    log(`Webhook listener started on port ${port}`);
    process.stdout.write(`[webhook] Listening on port ${port}\n`);
});

server.on('error', err => {
    process.stderr.write(`[webhook] Server error: ${err.message}\n`);
    process.exit(1);
});
