const { fetchBgproutesVisibility } = require("../../services/http-helpers");

// Compute routing visibility and prefix size distribution.
async function computeRoutingInfo(prefixes, visibilityData, prefixSizeData) {
  const ipv4Prefixes = prefixes.filter(function(p) { return !p.prefix.includes(":"); });
  const ipv6Prefixes = prefixes.filter(function(p) { return p.prefix.includes(":"); });
  var ipv4VisAvg = 0, ipv6VisAvg = 0, totalRisPeersV4 = 0, totalRisPeersV6 = 0;

  // Visibility API returns per-RIS-collector data
  // Each collector has ipv4_full_table_peer_count and ipv4_full_table_peers_not_seeing[]
  // Bug 3 fix: visibility API may timeout for large ASNs — handle gracefully
  var visibilities = (visibilityData && visibilityData.data && visibilityData.data.visibilities) || [];
  var v4Seeing = 0, v4Total = 0, v6Seeing = 0, v6Total = 0;
  var visTimedOut = !visibilityData || !visibilityData.data;
  visibilities.forEach(function(v) {
    if (!v || !v.probe) return;
    var v4PeerCount = v.ipv4_full_table_peer_count || 0;
    var v4NotSeeing = (v.ipv4_full_table_peers_not_seeing || []).length;
    var v6PeerCount = v.ipv6_full_table_peer_count || 0;
    var v6NotSeeing = (v.ipv6_full_table_peers_not_seeing || []).length;
    v4Total += v4PeerCount;
    v4Seeing += (v4PeerCount - v4NotSeeing);
    v6Total += v6PeerCount;
    v6Seeing += (v6PeerCount - v6NotSeeing);
  });
  if (v4Total > 0) ipv4VisAvg = Math.round((v4Seeing / v4Total) * 1000) / 10;
  if (v6Total > 0) ipv6VisAvg = Math.round((v6Seeing / v6Total) * 1000) / 10;
  // If visibility API timed out but we have prefixes, try bgproutes.io fallback
  if (visTimedOut && prefixes.length > 0) {
    var fallbackPrefix = prefixes.find(function(p) { return !p.prefix.includes(":"); });
    if (!fallbackPrefix) fallbackPrefix = prefixes[0];
    if (fallbackPrefix) {
      var bgprFallback = await fetchBgproutesVisibility(fallbackPrefix.prefix);
      if (bgprFallback && bgprFallback.vps_seeing > 0) {
        // Estimate visibility: % of VPs seeing the prefix (assume ~300 total RIS-equivalent VPs)
        var estimatedTotal = Math.max(bgprFallback.vps_seeing, 300);
        ipv4VisAvg = Math.round((bgprFallback.vps_seeing / estimatedTotal) * 1000) / 10;
        ipv6VisAvg = -1; // bgproutes fallback is per-prefix, not per-AF aggregate
        totalRisPeersV4 = bgprFallback.vps_seeing;
        console.log("[Visibility] RIPE Stat timed out, used bgproutes.io fallback for " + fallbackPrefix.prefix + ": " + bgprFallback.vps_seeing + " VPs seeing it");
      } else {
        ipv4VisAvg = -1;
        ipv6VisAvg = -1;
        console.log("[Visibility] RIPE Stat timed out and bgproutes.io fallback returned no data");
      }
    } else {
      ipv4VisAvg = -1;
      ipv6VisAvg = -1;
    }
  }
  totalRisPeersV4 = v4Total;
  totalRisPeersV6 = v6Total;

  // Prefix size distribution: data.ipv4[] and data.ipv6[] arrays with {size, count}
  var psdData = (prefixSizeData && prefixSizeData.data) || {};
  var psV4 = (psdData.ipv4 || []).map(function(e) { return { size: e.size, count: e.count }; }).sort(function(a,b){ return a.size - b.size; });
  var psV6 = (psdData.ipv6 || []).map(function(e) { return { size: e.size, count: e.count }; }).sort(function(a,b){ return a.size - b.size; });

  return {
    ipv4_prefixes: ipv4Prefixes.length,
    ipv6_prefixes: ipv6Prefixes.length,
    ipv4_visibility_avg: ipv4VisAvg,
    ipv6_visibility_avg: ipv6VisAvg,
    total_ris_peers_v4: totalRisPeersV4,
    total_ris_peers_v6: totalRisPeersV6,
    prefix_sizes_v4: psV4,
    prefix_sizes_v6: psV6,
  };
}

module.exports = { computeRoutingInfo };
