import { parse } from '@arbiter/evidence-dsl/parser/GeneratedParser';
import { RuleGenerator } from '@arbiter/evidence-dsl/generator/RuleGenerator';
import { Arbiter } from '../../src/core/Arbiter.js';

const dsl = [
  'fact level_check(session: Session, target: string)',
  '',
  'evidence high_level_access(session: Session) {',
  '  level_check(session, target) |E| { E.level >= 2 }',
  '}',
  '',
  'evidence suspended_block(session: Session) {',
  '  level_check(session, target) |E| { isSuspended(E.granted_by) }',
  '}',
  '',
  'evidence active_block(session: Session) {',
  '  level_check(session, target) |E| { isActive(E.granted_by) }',
  '}',
  '',
  'evidence time_filter(session: Session) {',
  '  level_check(session, target) |E| { E.expires_at > now() - 3600000 }',
  '}',
].join('\n');

const ast = parse(dsl);
const generator = new RuleGenerator();
const result = generator.generateRules(ast);
console.log('Generated rules:', result.generatedCount);

const arbiter = new Arbiter();

const configs = Array.from(generator.generatedRules.entries());
for (const [name, config] of configs) {
  arbiter.setRelationConfig(name, config);
  console.log('Registered:', name,
    '| filter:', config.attributeFilter ? config.attributeFilter.conditions.length + ' conditions' : 'none');
}

arbiter.addNode('session:s1', 'user');
arbiter.addNode('node:t1', 'target');
arbiter.addNode('node:t2', 'target');
arbiter.addNode('node:t3', 'target');
arbiter.addNode('node:t4', 'target');

// level=3, granted_by="admin" — passes >= 2, not suspended
arbiter.addRelation('session:s1', 'level_check', 'node:t1', { possibility: 1.0, attributes: { level: 3, granted_by: 'admin' } });
// level=1, granted_by=null — fails >= 2, IS suspended
arbiter.addRelation('session:s1', 'level_check', 'node:t2', { possibility: 1.0, attributes: { level: 1 } });
// level=5, granted_by="system" — passes >= 2, not suspended
arbiter.addRelation('session:s1', 'level_check', 'node:t3', { possibility: 1.0, attributes: { level: 5, granted_by: 'system' } });
// expires_at in past — fails time filter
arbiter.addRelation('session:s1', 'level_check', 'node:t4', { possibility: 1.0, attributes: { level: 5, expires_at: Date.now() - 7200000 } });

const tests = [
  { rule: 'high_level_access', target: 'node:t1', expect: 'PASS', reason: 'level=3 >= 2' },
  { rule: 'high_level_access', target: 'node:t2', expect: 'FAIL', reason: 'level=1 < 2' },
  { rule: 'high_level_access', target: 'node:t3', expect: 'PASS', reason: 'level=5 >= 2' },
  { rule: 'suspended_block', target: 'node:t1', expect: 'FAIL', reason: 'granted_by=admin not suspended' },
  { rule: 'suspended_block', target: 'node:t2', expect: 'PASS', reason: 'no granted_by means suspended' },
  { rule: 'active_block', target: 'node:t1', expect: 'PASS', reason: 'granted_by=admin is active' },
  { rule: 'active_block', target: 'node:t2', expect: 'FAIL', reason: 'no granted_by means not active' },
  { rule: 'time_filter', target: 'node:t1', expect: 'PASS', reason: 'no expires_at attribute — never expires' },
  { rule: 'time_filter', target: 'node:t4', expect: 'FAIL', reason: 'expires_at in past' },
];

console.log('');
for (const t of tests) {
  const r = arbiter.check('session:s1', t.rule, t.target);
  const passed = r.possibility > 0;
  const expected = t.expect === 'PASS' ? true : false;
  const status = passed === expected ? '✓' : '✗ MISMATCH';
  console.log(status, t.rule, '→', t.target, '| possibility:', r.possibility, '|', t.reason);
}
