import assert from "node:assert/strict"
import {
  disableRipeEnqueueForTests,
  disableRipePersistForTests,
  enqueueRipeMisses,
  flushRipeQueueForTests,
  lookupRipeCached,
  resetRipeCacheForTests,
  ripeFetchCountForTests,
  ripeLastCandidateCountForTests,
  seedRipeCacheForTests,
  setRipeFetchForTests,
} from "./traffic-flow-ripe.js"

disableRipePersistForTests()
resetRipeCacheForTests()
disableRipeEnqueueForTests()

assert.equal(lookupRipeCached("10.1.1.8")?.ok, false)
assert.equal(lookupRipeCached("192.168.0.1")?.ok, false)
assert.equal(lookupRipeCached("100.64.1.2")?.ok, false)
assert.equal(ripeFetchCountForTests(), 0)

seedRipeCacheForTests({
  prefix: "1.2.3.0/24",
  asn: 64500,
  country: "NL",
  lat: 52.3,
  lng: 4.9,
  holder: "TEST",
  ok: true,
  fetchedAt: Date.now(),
})
assert.equal(lookupRipeCached("1.2.3.10")?.country, "NL")
assert.equal(lookupRipeCached("1.2.3.10")?.asn, 64500)
assert.equal(ripeFetchCountForTests(), 0)

resetRipeCacheForTests()
disableRipePersistForTests()
setRipeFetchForTests(async (input) => {
  const url = String(input)
  const body = url.includes("network-info")
    ? { data: { prefix: "8.8.8.0/24", asns: ["15169"] } }
    : url.includes("maxmind-geo-lite")
      ? { data: { located_resources: [{ locations: [{ country: "US", latitude: 37.4, longitude: -122.1 }] }] } }
      : { data: { holder: "GOOGLE" } }
  return new Response(JSON.stringify(body), { status: 200, headers: { "Content-Type": "application/json" } })
})
enqueueRipeMisses(["8.8.8.8"])
await flushRipeQueueForTests()
assert.equal(lookupRipeCached("8.8.8.8")?.country, "US")
assert.equal(lookupRipeCached("8.8.8.10")?.prefix, "8.8.8.0/24")
const afterFirst = ripeFetchCountForTests()
assert.ok(afterFirst >= 2)
enqueueRipeMisses(["8.8.8.10"])
await flushRipeQueueForTests()
assert.equal(ripeFetchCountForTests(), afterFirst)

resetRipeCacheForTests()
disableRipePersistForTests()
setRipeFetchForTests(async () => {
  throw new Error("timeout")
})
enqueueRipeMisses(["203.0.113.50"])
await flushRipeQueueForTests()
const neg = lookupRipeCached("203.0.113.50")
assert.equal(neg?.ok, false)
const afterNeg = ripeFetchCountForTests()
enqueueRipeMisses(["203.0.113.50"])
await flushRipeQueueForTests()
assert.equal(ripeFetchCountForTests(), afterNeg)

resetRipeCacheForTests()
disableRipePersistForTests()
seedRipeCacheForTests({
  prefix: "1.1.1.0/24",
  asn: 13335,
  country: "?",
  lat: null,
  lng: null,
  holder: "CLOUDFLARENET, US",
  ok: true,
  fetchedAt: Date.now(),
})
assert.equal(lookupRipeCached("1.1.1.1")?.country, "US")
assert.ok(lookupRipeCached("1.1.1.1")?.country !== "?")

resetRipeCacheForTests()
disableRipePersistForTests()
setRipeFetchForTests(async (input) => {
  const url = String(input)
  const body = url.includes("network-info")
    ? { data: { prefix: "1.0.0.0/24", asns: ["13335"] } }
    : url.includes("maxmind-geo-lite")
      ? { data: { located_resources: [{ locations: [{ country: "?" }] }] } }
      : { data: { holder: "CLOUDFLARENET, US" } }
  return new Response(JSON.stringify(body), { status: 200, headers: { "Content-Type": "application/json" } })
})
enqueueRipeMisses(["1.0.0.1"])
await flushRipeQueueForTests()
assert.equal(lookupRipeCached("1.0.0.1")?.country, "US")
assert.equal(lookupRipeCached("1.0.0.1")?.asn, 13335)

resetRipeCacheForTests()
disableRipePersistForTests()
for (let i = 0; i < 3000; i++) {
  const o2 = Math.floor(i / 256)
  const o3 = i % 256
  seedRipeCacheForTests({
    prefix: `203.${o2}.${o3}.0/24`,
    asn: 64500,
    country: "NL",
    lat: null,
    lng: null,
    holder: "NOISE",
    ok: true,
    fetchedAt: Date.now(),
  })
}
seedRipeCacheForTests({
  prefix: "8.8.8.0/24",
  asn: 15169,
  country: "US",
  lat: null,
  lng: null,
  holder: "GOOGLE",
  ok: true,
  fetchedAt: Date.now(),
})
assert.equal(lookupRipeCached("8.8.8.8")?.asn, 15169)
assert.ok(
  ripeLastCandidateCountForTests() < 8,
  `index should not scan all prefixes, got ${ripeLastCandidateCountForTests()}`,
)

console.log("traffic-flow-ripe.test.ts: ok")
