import { describe, expect, it } from 'vitest'
import { isMeteringValidationError } from './errors.js'
import { rate } from './rate.js'
import type { RatingRule } from './types.js'

const rule = (numerator: bigint, denominator: bigint): RatingRule => ({
  meter: 'api.calls',
  ruleVersion: 'rule-1',
  effectiveFrom: new Date('2026-07-01T00:00:00.000Z'),
  numerator,
  denominator,
})

describe('rate', () => {
  it('converts exact bigint ratios without floating-point arithmetic', () => {
    expect(rate(12n, rule(5n, 3n))).toBe(20n)
    expect(rate(7n, rule(3n, 2n))).toBe(10n)
  })

  it('truncates fractional results toward zero', () => {
    expect(rate(5n, rule(1n, 2n))).toBe(2n)
    expect(rate(5n, rule(-1n, 2n))).toBe(-2n)
  })

  it('rejects a non-positive denominator with a typed validation error', () => {
    for (const denominator of [0n, -1n]) {
      let thrown: unknown
      try {
        rate(1n, rule(1n, denominator))
      } catch (error) {
        thrown = error
      }

      expect(isMeteringValidationError(thrown)).toBe(true)
      expect(thrown).toMatchObject({ field: 'rule.denominator' })
    }
  })
})
