import { describe, expect, it } from 'vitest'
import { reviveStaleSplit } from './revive.js'
import { isCheckoutWireError } from './errors.js'

describe('reviveStaleSplit', () => {
  it('revives both bigint fields from string-encoded wire JSON', () => {
    const wire = { removed: ['v1'], updated: [{ variantId: 'v2', was: '1000', now: '1200' }] }
    const r = reviveStaleSplit(wire)
    expect(r.removed).toEqual(['v1'])
    expect(r.updated).toEqual([{ variantId: 'v2', was: 1000n, now: 1200n }])
  })

  it('accepts number-encoded safe-integer amounts', () => {
    const r = reviveStaleSplit({ removed: [], updated: [{ variantId: 'v', was: 50, now: 60 }] })
    expect(r.updated[0]).toEqual({ variantId: 'v', was: 50n, now: 60n })
  })

  it('throws CheckoutWireError on a non-object', () => {
    try {
      reviveStaleSplit(null)
      throw new Error('should have thrown')
    } catch (e) {
      expect(isCheckoutWireError(e)).toBe(true)
    }
  })

  it('throws CheckoutWireError when removed is not a string array', () => {
    expect(() => reviveStaleSplit({ removed: [1], updated: [] })).toThrow()
  })

  it('throws CheckoutWireError on a malformed amount (≥2^53 number / non-integer string)', () => {
    expect(() => reviveStaleSplit({ removed: [], updated: [{ variantId: 'v', was: 'abc', now: '1' }] })).toThrow()
    expect(() => reviveStaleSplit({ removed: [], updated: [{ variantId: 'v', was: 2 ** 53, now: 1 }] })).toThrow()
  })
})
describe('wire-trust hardening (uniform -react sweep)', () => {
  it('amount string over 21 digits → CheckoutWireError (bounded BigInt parse, no DoS)', () => {
    for (const long of ['9'.repeat(22), '-' + '9'.repeat(22), '1'.repeat(1_000_000)]) {
      try {
        reviveStaleSplit({ removed: [], updated: [{ variantId: 'v', was: long, now: '1' }] })
        throw new Error('should have thrown')
      } catch (e) {
        expect(isCheckoutWireError(e)).toBe(true)
      }
    }
  })

  it('21-digit amount string (boundary) still parses exactly', () => {
    const max = '9'.repeat(21)
    const r = reviveStaleSplit({ removed: [], updated: [{ variantId: 'v', was: max, now: '-' + max }] })
    expect(r.updated[0]!.was).toBe(BigInt(max))
    expect(r.updated[0]!.now).toBe(-BigInt(max))
  })
})
