const localDb = require("../../local-db-client");
const { bgproutesResultCache, resultCacheGet, resultCacheSet } = require("../caches/response-caches");

// BGP endpoint (LOCAL DB): /api/bgp?asn=X (or prefix=X)
// Queries local PostgreSQL bgp_routes table — zero external API calls
async function handleBgp(req, res, url) {
    const rawAsn = (url.searchParams.get("asn") || "").replace(/[^0-9]/g, "");
    const prefix = url.searchParams.get("prefix") || "";
    if (!rawAsn && !prefix) {
      res.writeHead(400);
      return res.end(JSON.stringify({ error: "Need asn or prefix parameter" }));
    }
    const cacheKey = rawAsn || prefix;
    const cached = resultCacheGet(bgproutesResultCache, cacheKey);
    if (cached !== undefined) {
      res.writeHead(200, { "Content-Type": "application/json", "X-Cache": "HIT" });
      return res.end(JSON.stringify(cached));
    }
    const start = Date.now();
    try {
      const result = {
        meta: { timestamp: new Date().toISOString(), source: "local_bgp_db" },
        bgp_status: null,
        threat_intel: null,
      };

      // ---- BGP Status (local DB lookup) ----
      if (prefix) {
        // Prefix lookup: Get BGP status for this prefix
        const bgpStatus = await localDb.getBgpStatus(prefix);
        if (bgpStatus) {
          result.bgp_status = {
            prefix,
            announced: bgpStatus.announced,
            origin_asns: bgpStatus.origin_asns,
            visibility_percent: bgpStatus.visibility_percent,
            last_seen: bgpStatus.last_seen,
            source: "local_bgp",
          };
          // Check for hijack (multiple origin ASNs). null means the check itself
          // failed (DB error) -- distinct from a genuine single/no-origin result.
          const hijackAsns = await localDb.checkBgpHijack(prefix);
          if (hijackAsns === null) {
            result.bgp_status.hijack_check_unavailable = true;
          } else if (hijackAsns.length > 1) {
            result.bgp_status.hijack_warning = {
              detected: true,
              origin_asns: hijackAsns,
              message: `Multiple origin ASNs detected for ${prefix}`,
            };
          }
        }
      } else if (rawAsn) {
        // ASN lookup: Get all announced prefixes for this ASN
        const prefixes = await localDb.getAnnouncedPrefixes(rawAsn);
        if (prefixes && prefixes.length > 0) {
          result.bgp_status = {
            asn: rawAsn,
            announced_count: prefixes.length,
            prefixes: prefixes.slice(0, 50).map((p) => ({
              prefix: p.prefix,
              origin_asn: p.origin_asn,
              visibility_percent: p.visibility_percent,
              last_seen: p.last_seen,
            })),
            source: "local_bgp",
          };
        } else {
          result.bgp_status = {
            asn: rawAsn,
            announced: false,
            announced_count: 0,
            message: "No prefixes found for this ASN in local BGP table",
            source: "local_bgp",
          };
        }
      }

      // ---- Threat Intelligence (local cache lookup) ----
      // If we have an IP context, look up threat intel
      if (prefix && prefix.includes(".")) {
        // Extract IP from prefix (e.g., "1.1.1.0/24" → "1.1.1.0")
        const ipAddr = prefix.split("/")[0];
        const threat = await localDb.getThreatIntel(ipAddr);
        if (threat) {
          result.threat_intel = {
            ip_address: threat.ip_address,
            threat_level: threat.threat_level,
            confidence_score: threat.confidence_score,
            source: threat.source,
            cached_at: threat.cached_at,
          };
        }
      }

      result.meta.duration_ms = Date.now() - start;
      resultCacheSet(bgproutesResultCache, cacheKey, result);
      res.writeHead(200, { "Content-Type": "application/json" });
      return res.end(JSON.stringify(result, null, 2));
    } catch (err) {
      console.error("[/api/bgp] Error:", err.message);
      res.writeHead(500);
      return res.end(JSON.stringify({ error: "BGP query failed", message: err.message }));
    }

}

module.exports = { handleBgp };
