/**
 * Event Schema Validation Tests
 * Ensures events conform to AsyncAPI specification
 */

import { describe, it, expect } from '@jest/globals';
import { readFileSync } from 'fs';
import { join } from 'path';
import * as yaml from 'js-yaml';
import Ajv from 'ajv';
import addFormats from 'ajv-formats';

const ASYNCAPI_SPEC = join(__dirname, '../../../api/packages/asyncapi/asyncapi.yaml');

describe('AsyncAPI Event Schema Validation', () => {
  let asyncapiSpec: any;
  let ajv: Ajv;

  beforeAll(() => {
    const specContent = readFileSync(ASYNCAPI_SPEC, 'utf-8');
    asyncapiSpec = yaml.load(specContent);
    ajv = new Ajv();
    addFormats(ajv);
  });

  it('should have valid AsyncAPI structure', () => {
    expect(asyncapiSpec).toHaveProperty('asyncapi');
    expect(asyncapiSpec.asyncapi).toMatch(/^3\.\d+\.\d+$/);
    expect(asyncapiSpec).toHaveProperty('channels');
  });

  it('should have all required event channels', () => {
    const requiredChannels = [
      'triggers.created',
      'triggers.state.updated',
      'liens.placed',
      'liens.reduced',
      'liens.released',
      'packets.generated',
      'packets.dispatched',
      'packets.acknowledged',
      'bridge.locked',
      'bridge.unlocked',
      'compliance.updated',
      'policy.updated',
    ];

    requiredChannels.forEach((channel) => {
      expect(asyncapiSpec.channels[channel]).toBeDefined();
    });
  });

  it('should have event envelope schema', () => {
    expect(asyncapiSpec.components).toHaveProperty('schemas');
    expect(asyncapiSpec.components.schemas).toHaveProperty('EventEnvelope');
    
    const envelopeSchema = asyncapiSpec.components.schemas.EventEnvelope;
    expect(envelopeSchema.required).toContain('eventId');
    expect(envelopeSchema.required).toContain('eventType');
    expect(envelopeSchema.required).toContain('occurredAt');
    expect(envelopeSchema.required).toContain('payload');
  });
});
