import { describe, expect, it } from 'vitest'
import { isVendorNotFoundError } from './errors.js'
import { assertVendorCanSell, assertVendorOwnership } from './authz.js'
import { resolveCommissionRate, setVendorCommissionRate } from './commission.js'
import { approveVendor, suspendVendor } from './vendor.js'
import { ADMIN, USER_A, freshDb } from './test-helpers.js'

// Gate-4 Finding 4 (security-guard, pre-merge): a malformed (non-UUID) id MUST NOT
// reach the `uuid` column — a raw driver error would 500, leak the SQL query
// structure, break the typed-error-family contract (no bare throw across the seam),
// and create a malformed-vs-nonexistent oracle. Each id-taking primitive guards the
// id shape with UUID_RE and throws the typed VendorNotFoundError (404) — byte-identical
// IN SHAPE to a genuinely-nonexistent id, so a bad-format id reveals nothing.
//
// TEETH: revert any UUID_RE guard and the malformed id hits eq(vendor.id, …) → a raw
// `Error` (name 'Error', no code/httpStatus) → isVendorNotFoundError(e) === false → RED.
const MALFORMED = 'not-a-uuid'
const NONEXISTENT = '99999999-9999-4999-8999-999999999999'

describe('secaudit-marketplace-malformed-id-no-leak', () => {
  it('assertVendorOwnership: malformed id → typed VendorNotFoundError (404), never a raw 500', async () => {
    const db = await freshDb()
    await expect(
      assertVendorOwnership(db, { userId: USER_A }, MALFORMED),
    ).rejects.toSatisfy((e) => isVendorNotFoundError(e))
    await expect(
      assertVendorOwnership(db, { userId: USER_A }, MALFORMED),
    ).rejects.toMatchObject({ code: 'VENDOR_NOT_FOUND', httpStatus: 404 })
  })

  it('assertVendorCanSell: malformed id → typed VendorNotFoundError', async () => {
    const db = await freshDb()
    await expect(assertVendorCanSell(db, MALFORMED)).rejects.toSatisfy((e) =>
      isVendorNotFoundError(e),
    )
  })

  it('resolveCommissionRate: malformed id → typed VendorNotFoundError', async () => {
    const db = await freshDb()
    await expect(resolveCommissionRate(db, MALFORMED)).rejects.toSatisfy((e) =>
      isVendorNotFoundError(e),
    )
  })

  it('setVendorCommissionRate: malformed id → typed VendorNotFoundError (admin + range gates pass first)', async () => {
    const db = await freshDb()
    await expect(
      db.transaction((tx) => setVendorCommissionRate(tx, MALFORMED, ADMIN, 500)),
    ).rejects.toSatisfy((e) => isVendorNotFoundError(e))
  })

  it('approveVendor: malformed id → typed VendorNotFoundError (admin gate passes first)', async () => {
    const db = await freshDb()
    await expect(
      db.transaction((tx) => approveVendor(tx, MALFORMED, ADMIN)),
    ).rejects.toSatisfy((e) => isVendorNotFoundError(e))
  })

  it('suspendVendor: malformed id → typed VendorNotFoundError (admin gate passes first)', async () => {
    const db = await freshDb()
    await expect(
      db.transaction((tx) => suspendVendor(tx, MALFORMED, ADMIN)),
    ).rejects.toSatisfy((e) => isVendorNotFoundError(e))
  })

  it('malformed id is byte-identical IN SHAPE to a genuinely-nonexistent id (no oracle)', async () => {
    const db = await freshDb()
    const shapeOf = (e: unknown) => {
      const err = e as { name: string; code: string; httpStatus: number }
      return { name: err.name, code: err.code, httpStatus: err.httpStatus }
    }
    const malformed = await resolveCommissionRate(db, MALFORMED).then(
      () => null,
      shapeOf,
    )
    const nonexistent = await resolveCommissionRate(db, NONEXISTENT).then(
      () => null,
      shapeOf,
    )
    expect(malformed).toEqual(nonexistent)
    expect(malformed).toEqual({
      name: 'VendorNotFoundError',
      code: 'VENDOR_NOT_FOUND',
      httpStatus: 404,
    })
  })
})
