import { test, describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { setupChainRuleTestGraph } from './helpers.js';

describe('ChainRule Comprehensive Tests', () => {

  describe('Value Extraction and Aggregation', () => {
    it('extracts and sums values from chain endpoints', () => {
      const arbiter = setupChainRuleTestGraph();

      // Test: user → group → project → budget (extract budget values)
      arbiter.setRelationConfig('user_budget_access', {
        type: 'chain',
        steps: [
          { relation: 'member_of', direction: 'out' },    // user → group
          { relation: 'manages', direction: 'out' },      // group → project
          { relation: 'has_budget', direction: 'out' }    // project → budget
        ],
        extractValues: true,
        extractFrom: 2,                 // Extract from step 2 (projects)
        extractRelation: 'has_budget',  // Extract budget values
        valueAggregation: 'sum'         // Sum all budgets
      });

      // Alice should have access to engineering budgets
      const result1 = arbiter.check('user:alice', 'user_budget_access', 'budget:tech-2024');

      // Authorization should succeed
      assert.equal(result1.possibility, 1);
      assert.equal(result1.reason, 'allow_rule_matched');

      // Values should NOT be in the authorization result (they're internal only)
      assert.equal(result1.value, undefined);
      assert.equal(result1.hasValue, undefined);

      // The ChainRule internally calculated values for potential use by other rules,
      // but authorization results only contain allow/deny possibilities
    });

    it('aggregates values using max aggregation', () => {
      const arbiter = setupChainRuleTestGraph();

      arbiter.setRelationConfig('max_project_budget', {
        type: 'chain',
        steps: [
          { relation: 'member_of', direction: 'out' },
          { relation: 'manages', direction: 'out' },
          { relation: 'has_budget', direction: 'out' }
        ],
        extractValues: true,
        extractFrom: 2,
        extractRelation: 'has_budget',
        valueAggregation: 'max'         // Use maximum budget
      });

      // Alice should have access to budgets
      const result = arbiter.check('user:alice', 'max_project_budget', 'budget:tech-2024');
      assert.equal(result.possibility, 1);

      // Values are internal only, not exposed in authorization results
      assert.equal(result.value, undefined);
    });

    it('aggregates values using min aggregation', () => {
      const arbiter = setupChainRuleTestGraph();

      arbiter.setRelationConfig('min_project_cost', {
        type: 'chain',
        steps: [
          { relation: 'member_of', direction: 'out' },
          { relation: 'manages', direction: 'out' },
          { relation: 'has_cost', direction: 'out' }
        ],
        extractValues: true,
        extractFrom: 2,
        extractRelation: 'has_cost',
        valueAggregation: 'min'         // Use minimum cost
      });

      // Alice should have access to cost information
      const result = arbiter.check('user:alice', 'min_project_cost', 'budget:tech-2024');
      assert.equal(result.possibility, 1);

      // Values are internal only, not exposed in authorization results
      assert.equal(result.value, undefined);
    });
  });
});
