#!/usr/bin/env node
// Download Cytoscape.js + cose-bilkent layout plugin from CDN.
// Skips download if files exist and are < 30 days old.
//
// Usage:
//   node scripts/download/download-cytoscape.js

import fs   from 'fs';
import path from 'path';
import https from 'https';
import { fileURLToPath } from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const PUBLIC_JS = path.join(__dirname, '../../site/public/js');

const ASSETS = [
  {
    url:  'https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.29.2/cytoscape.min.js',
    out:  'cytoscape.min.js',
    name: 'Cytoscape.js 3.29.2',
  },
  {
    url:  'https://cdn.jsdelivr.net/npm/cytoscape-cose-bilkent@4.1.0/cytoscape-cose-bilkent.js',
    out:  'cytoscape-cose-bilkent.js',
    name: 'cose-bilkent layout 4.1.0',
  },
];

const MAX_AGE_MS = 30 * 24 * 60 * 60 * 1000;

function download(url, dest) {
  return new Promise((resolve, reject) => {
    https.get(url, (res) => {
      if (res.statusCode === 301 || res.statusCode === 302) {
        return download(res.headers.location, dest).then(resolve).catch(reject);
      }
      if (res.statusCode !== 200) {
        return reject(new Error(`HTTP ${res.statusCode}: ${url}`));
      }
      const chunks = [];
      res.on('data', (c) => chunks.push(c));
      res.on('end', () => {
        fs.mkdirSync(path.dirname(dest), { recursive: true });
        fs.writeFileSync(dest, Buffer.concat(chunks));
        resolve();
      });
    }).on('error', reject);
  });
}

async function main() {
  for (const asset of ASSETS) {
    const dest = path.join(PUBLIC_JS, asset.out);

    if (fs.existsSync(dest)) {
      const age = Date.now() - fs.statSync(dest).mtimeMs;
      if (age < MAX_AGE_MS) {
        const kb = (fs.statSync(dest).size / 1024).toFixed(1);
        console.log(`skip  ${asset.name} (${kb} kB, cached)`);
        continue;
      }
    }

    process.stdout.write(`get   ${asset.name} ... `);
    try {
      await download(asset.url, dest);
      const kb = (fs.statSync(dest).size / 1024).toFixed(1);
      console.log(`ok (${kb} kB)`);
    } catch (err) {
      console.error(`\nfail  ${asset.name}: ${err.message}`);
      process.exit(1);
    }
  }
}

main();
