import { describe, test } from 'node:test';
import assert from 'node:assert/strict';
import { PeggyDSLParser } from '../../src/ast/parser/PeggyDSLParser.js';

describe('Peggy DSL Parser', () => {
  const parser = new PeggyDSLParser();

  test('Basic parsing', () => {
    const dsl = `
      definition User {
        role: string
        isActive: boolean
      }

      fact hasRole(user: User, role: string)

      evidence canRead(user: User, doc: Document) {
        hasRole(user, 'admin')
      }
    `;

    const program = parser.parse(dsl);
    assert.ok(program !== null, 'Program should be created');
    assert.ok(program.definitions.length === 1, 'Should have 1 definition');
    assert.ok(program.facts.length === 1, 'Should have 1 fact');
    assert.ok(program.evidence.length === 1, 'Should have 1 evidence');
  });

  test('Complex DSL parsing', () => {
    const dsl = `
      definition User {
        role: string
        isActive: boolean
        clearance: string BEHAVES {
          blurring adaptive confidence_95
        } CACHE eager
      }

      fact hasRole(user: User, role: string) CACHE eager
      fact isMember(user: User, group: Group) transitive CACHE lazy

      evidence canRead(user: User, doc: Document) {
        hasRole(user, 'admin')

        isMember(user, *group) {
          canRead(group, doc)
        } limit 5

        WHEN hasRole(user, 'admin') UNLESS isSuspended(user)
      }
    `;

    const program = parser.parse(dsl);
    assert.ok(program !== null, 'Program should be created');
    assert.ok(program.definitions.length === 1, 'Should have 1 definition');
    assert.ok(program.facts.length === 2, 'Should have 2 facts');
    assert.ok(program.evidence.length === 1, 'Should have 1 evidence');
  });

  test('Error handling', () => {
    const invalidDSL = `
      definition User {
        role: string
        // Missing closing brace

      fact hasRole(user: User, role: string)
      // Missing semicolon
    `;

    assert.throws(
      () => parser.parse(invalidDSL),
      /Parsing failed/,
      'Should have parsing error message'
    );
  });

  test('Validation', () => {
    const validDSL = `
      definition User {
        role: string
        isActive: boolean
      }

      fact hasRole(user: User, role: string)
    `;

    const invalidDSL = `
      definition User {
        role: string
        // Missing closing brace
    `;

    const validResult = parser.validate(validDSL);
    assert.ok(validResult.success, 'Valid DSL should pass validation');
    assert.ok(validResult.program !== null, 'Valid DSL should return program');

    const invalidResult = parser.validate(invalidDSL);
    assert.ok(!invalidResult.success, 'Invalid DSL should fail validation');
    assert.ok(invalidResult.errors.length > 0, 'Should have validation errors');
  });
});
