import { describe, expect, it } from 'vitest'
import {
  CapabilityRightSchema,
  CapabilityTokenSchema,
  EnrollResultSchema,
  NotImplementedInContractsError,
  PairingCodeRecordSchema,
  verifyCapabilityToken,
} from '../src/index.js'

const UUID = '22222222-2222-4222-8222-222222222222'
const TS = '2026-07-01T00:00:00.000Z'

describe('§4.3 CapabilityToken shape validation', () => {
  const valid = {
    sub: 'device:1',
    aud: 'alice',
    host: UUID,
    rights: ['attach'],
    iat: 1000,
    exp: 2000,
    jti: 'jti-1',
  }

  it('accepts a well-formed token body', () => {
    expect(CapabilityTokenSchema.parse(valid).rights).toEqual(['attach'])
  })

  it('rejects empty rights', () => {
    expect(CapabilityTokenSchema.safeParse({ ...valid, rights: [] }).success).toBe(false)
  })

  it('rejects duplicate rights', () => {
    expect(
      CapabilityTokenSchema.safeParse({ ...valid, rights: ['attach', 'attach'] }).success,
    ).toBe(false)
  })

  it('rejects exp <= iat', () => {
    expect(CapabilityTokenSchema.safeParse({ ...valid, exp: 1000 }).success).toBe(false)
  })

  it('rejects an unknown right', () => {
    expect(CapabilityTokenSchema.safeParse({ ...valid, rights: ['destroy'] }).success).toBe(false)
  })

  it('verifyCapabilityToken is a frozen stub (crypto verify owned by P5)', () => {
    expect(() => verifyCapabilityToken('raw', 'alice', Date.now())).toThrow(
      NotImplementedInContractsError,
    )
  })
})

describe('CapabilityRight enum — enroll right (FIX C-native-1)', () => {
  const validBody = {
    sub: 'device:1',
    aud: 'alice',
    host: UUID,
    rights: ['attach'],
    iat: 1000,
    exp: 2000,
    jti: 'jti-1',
  }

  it('accepts the new enroll right', () => {
    expect(CapabilityRightSchema.parse('enroll')).toBe('enroll')
  })

  it('still accepts the existing rights (backward compatible)', () => {
    expect(CapabilityRightSchema.parse('attach')).toBe('attach')
    expect(CapabilityRightSchema.parse('manage')).toBe('manage')
    expect(CapabilityRightSchema.parse('kill')).toBe('kill')
  })

  it('still rejects an unknown right', () => {
    expect(() => CapabilityRightSchema.parse('destroy')).toThrow()
  })

  it('accepts a token body carrying the enroll right', () => {
    expect(CapabilityTokenSchema.parse({ ...validBody, rights: ['enroll'] }).rights).toEqual([
      'enroll',
    ])
  })
})

describe('§4.5 pairing / enroll shapes', () => {
  it('accepts a valid EnrollResult', () => {
    const rec = {
      hostId: UUID,
      subdomain: 'alice',
      cert: '-----BEGIN CERTIFICATE-----',
      caChain: '-----BEGIN CERTIFICATE-----',
      hostContentSecret: new Uint8Array([9, 8, 7]),
    }
    expect(EnrollResultSchema.parse(rec).hostContentSecret).toBeInstanceOf(Uint8Array)
  })

  it('rejects an EnrollResult with a non-bytes hostContentSecret', () => {
    expect(
      EnrollResultSchema.safeParse({
        hostId: UUID,
        subdomain: 'a',
        cert: 'c',
        caChain: 'c',
        hostContentSecret: 'not-bytes',
      }).success,
    ).toBe(false)
  })

  it('accepts a PairingCodeRecord (redeemed and unredeemed)', () => {
    expect(
      PairingCodeRecordSchema.parse({
        codeHash: 'h',
        accountId: UUID,
        expiresAt: TS,
        redeemedAt: null,
      }).redeemedAt,
    ).toBeNull()
    expect(
      PairingCodeRecordSchema.parse({
        codeHash: 'h',
        accountId: UUID,
        expiresAt: TS,
        redeemedAt: TS,
      }).redeemedAt,
    ).toBe(TS)
  })
})
