import { describe, it, expect, vi, beforeEach } from 'vitest'
import { ASPACollector } from '../collector'

describe('ASPACollector', () => {
  let collector: ASPACollector

  beforeEach(() => {
    collector = new ASPACollector()
    vi.clearAllMocks()
  })

  describe('collect', () => {
    it('should return array of adoption snapshots', async () => {
      const asns = [13335, 15169, 8452]
      const result = await collector.collect(asns, {
        maxRetries: 1,
        timeoutMs: 100,
        rateLimit: 1000,
      })

      expect(Array.isArray(result)).toBe(true)
      expect(result.length).toBe(asns.length)
      expect(result[0]).toHaveProperty('asn')
      expect(result[0]).toHaveProperty('hasASPA')
      expect(result[0]).toHaveProperty('providers')
      expect(result[0]).toHaveProperty('region')
    })

    it('should handle empty ASN list', async () => {
      const result = await collector.collect([], {
        maxRetries: 1,
        timeoutMs: 100,
        rateLimit: 100,
      })

      expect(result.length).toBe(0)
    })

    it('should infer regions correctly', async () => {
      const asns = [100, 10000, 40000, 4300000000]
      const result = await collector.collect(asns, {
        maxRetries: 1,
        timeoutMs: 100,
        rateLimit: 100,
      })

      const regions = result.map((s) => s.region)
      expect(regions.length).toBe(asns.length)
      expect(regions.every((r) => typeof r === 'string')).toBe(true)
    })

    it('should set hasASPA to false when no providers found', async () => {
      const asns = [13335]
      const result = await collector.collect(asns, {
        maxRetries: 1,
        timeoutMs: 100,
        rateLimit: 100,
      })

      expect(result[0].providers).toBeDefined()
      expect(Array.isArray(result[0].providers)).toBe(true)
    })

    it('should respect rate limiting', async () => {
      const asns = [13335, 15169, 8452]
      const startTime = Date.now()

      await collector.collect(asns, {
        maxRetries: 0,
        timeoutMs: 100,
        rateLimit: 2,
      })

      const duration = Date.now() - startTime
      const minDuration = (asns.length / 2) * 1000 - 500
      expect(duration).toBeGreaterThanOrEqual(minDuration - 200)
    })
  })

  describe('getQueueSize', () => {
    it('should return 0 initially', () => {
      expect(collector.getQueueSize()).toBe(0)
    })
  })
})
