const { fetchRipeStatCached } = require("../services/ripe-stat");
const { fetchBgproutesVisibility } = require("../services/http-helpers");
const { validateRPKIWithCache } = require("../services/rpki");

const BGPROUTES_API_KEY = process.env.BGPROUTES_API_KEY || "";

// Prefix Detail endpoint: /api/prefix/detail?prefix=X
async function handlePrefixDetail(req, res, url) {
    const prefix = url.searchParams.get("prefix") || "";
    if (!prefix) {
      res.writeHead(400);
      return res.end(JSON.stringify({ error: "Missing prefix parameter" }));
    }
    const start = Date.now();
    try {
      const [routingStatus, visibility] = await Promise.all([
        fetchRipeStatCached("https://stat.ripe.net/data/routing-status/data.json?resource=" + encodeURIComponent(prefix)),
        fetchRipeStatCached("https://stat.ripe.net/data/visibility/data.json?resource=" + encodeURIComponent(prefix)),
      ]);

      const origins = routingStatus?.data?.origins || [];
      const firstSeen = routingStatus?.data?.first_seen?.time || null;

      // RPKI validation: use local PostgreSQL database (sub-10ms, zero external API calls)
      let rpkiStatus = "unknown";
      let rpkiRoas = [];
      const originAsn = origins.length > 0 ? origins[0].asn : null;
      if (originAsn) {
        try {
          const localRpki = await validateRPKIWithCache(originAsn, prefix);
          rpkiStatus = localRpki.status;
          rpkiRoas = new Array(localRpki.validating_roas); // count only, no detail
        } catch (e) {
          console.error("[Prefix Detail] RPKI validation error:", e.message);
          rpkiStatus = "unknown";
          rpkiRoas = [];
        }
      }
      var visData = visibility?.data?.visibilities || [];
      var risPeersSeeingIt = visData.length > 0 ? visData.filter(v => v.ris_peers_seeing > 0).length : 0;
      var visibilitySource = "ripe_stat";
      // bgproutes.io fallback if RIPE Stat visibility returned no data
      if (visData.length === 0 && BGPROUTES_API_KEY) {
        var bgprVis = await fetchBgproutesVisibility(prefix);
        if (bgprVis && bgprVis.vps_seeing > 0) {
          risPeersSeeingIt = bgprVis.vps_seeing;
          visData = []; // keep empty, use risPeersSeeingIt
          visibilitySource = "bgproutes.io";
        }
      }

      // Try to get IRR data
      let irrStatus = "unknown";
      try {
        const whoisData = await fetchRipeStatCached("https://stat.ripe.net/data/whois/data.json?resource=" + encodeURIComponent(prefix));
        const records = whoisData?.data?.records || [];
        if (records.length > 0) irrStatus = "found";
      } catch(_e) {}

      const duration = Date.now() - start;
      return res.end(JSON.stringify({
        meta: { duration_ms: duration, timestamp: new Date().toISOString() },
        prefix: prefix,
        origins: origins.map(o => ({ asn: o.asn, prefix: o.prefix })),
        rpki: { status: rpkiStatus, validating_roas: rpkiRoas.length },
        irr_status: irrStatus,
        visibility: { ris_peers_seeing: risPeersSeeingIt, total_probes: visData.length || risPeersSeeingIt, source: visibilitySource },
        first_seen: firstSeen,
      }, null, 2));
    } catch (err) {
      res.writeHead(500);
      return res.end(JSON.stringify({ error: "Prefix detail failed", message: err.message }));
    }

}

module.exports = { handlePrefixDetail };
