const fs = require("fs");
const https = require("https");
const path = require("path");
const { UA } = require("./data/constants");
const { PEERINGDB_API_KEY } = require("./services/peeringdb");

// Repo root -- NOT this module's own directory. See hijack-monitoring/store.js
// for the same __dirname-fallback fix applied for the same reason.
const REPO_ROOT = path.join(__dirname, "..");

// PeeringDB Org → Country Cache (for Lia's Paradise). Exposed via a mutable
// state object (not a bare reassigned export) for the same reason as
// atlas-probes.js's atlasState -- the Map itself is reassigned wholesale on
// refresh, not just mutated in place.
const pdbOrgState = { map: new Map() }; // org_id → { country, name }

function fetchPdbOrgCountries() {
  var cacheFile = path.join(REPO_ROOT, ".pdb-org-cache.json");

  // Try disk cache first (valid for 24h)
  try {
    var stat = fs.statSync(cacheFile);
    var ageHours = (Date.now() - stat.mtimeMs) / 3600000;
    if (ageHours < 24) {
      var cached = JSON.parse(fs.readFileSync(cacheFile, "utf8"));
      pdbOrgState.map = new Map(Object.entries(cached));
      console.log("[PDB-ORG] Loaded " + pdbOrgState.map.size + " orgs from disk cache (" + Math.round(ageHours) + "h old)");
      return Promise.resolve();
    }
  } catch (_) { /* no cache or invalid */ }

  console.log("[PDB-ORG] Fetching PeeringDB org countries (fresh)...");
  return new Promise(function(resolve) {
    var chunks = [];
    var req = https.get("https://www.peeringdb.com/api/org?status=ok&depth=0", {
      headers: {
        "User-Agent": UA,
        // Bug fix 2026-07-16: a bare `PEERINGDB_API_KEY ? ... : undefined`
        // sets the Authorization header value to `undefined` when no key is
        // configured. Node 22's stricter header validation throws
        // synchronously on that (ERR_HTTP_INVALID_HEADER_VALUE) instead of
        // omitting the header, crashing the whole process at startup via
        // this function's unhandled rejection (found empirically while
        // trying to boot server.js locally without a real PeeringDB key).
        // Conditionally spread the key in instead so the header key itself
        // is simply absent when unconfigured.
        ...(PEERINGDB_API_KEY ? { "Authorization": "Api-Key " + PEERINGDB_API_KEY } : {}),
      },
      timeout: 120000,
    }, function(res) {
      if (res.statusCode !== 200) {
        console.error("[PDB-ORG] HTTP " + res.statusCode + " — using stale cache or empty");
        resolve();
        return;
      }
      res.on("data", function(chunk) { chunks.push(chunk); });
      res.on("end", function() {
        try {
          var body = Buffer.concat(chunks).toString("utf8");
          var data = JSON.parse(body);
          if (data && data.data) {
            pdbOrgState.map = new Map();
            var cacheObj = {};
            data.data.forEach(function(o) {
              if (o.id && o.country) {
                pdbOrgState.map.set(o.id, { country: o.country, name: o.name || "" });
                cacheObj[o.id] = { country: o.country, name: o.name || "" };
              }
            });
            // Save to disk cache
            try { fs.writeFileSync(cacheFile, JSON.stringify(cacheObj)); } catch (_) {}
            console.log("[PDB-ORG] Loaded " + pdbOrgState.map.size + " org→country mappings (cached to disk)");
          }
        } catch (e) {
          console.error("[PDB-ORG] Parse error:", e.message);
        }
        resolve();
      });
    });
    req.on("error", function(e) {
      console.error("[PDB-ORG] Fetch error:", e.message);
      resolve();
    });
    req.on("timeout", function() {
      console.error("[PDB-ORG] Timeout after 120s");
      req.destroy();
      resolve();
    });
  });
}

module.exports = { pdbOrgState, fetchPdbOrgCountries };
