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

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

  describe('Edge Cases and Error Handling', () => {
    it('handles empty chains gracefully', () => {
      const arbiter = setupChainRuleTestGraph();

      arbiter.setRelationConfig('empty_chain', {
        type: 'chain',
        steps: []  // Empty steps
      });

      const result = arbiter.check('user:alice', 'empty_chain', 'project:web-app');
      assert.equal(result.possibility, 0);
      assert.equal(result.reason, 'no_chain_steps_defined');
    });

    it('handles broken chains correctly', () => {
      const arbiter = setupChainRuleTestGraph();

      arbiter.setRelationConfig('broken_chain', {
        type: 'chain',
        steps: [
          { relation: 'member_of', direction: 'out' },
          { relation: 'nonexistent_relation', direction: 'out' }  // Broken link
        ]
      });

      const result = arbiter.check('user:alice', 'broken_chain', 'project:web-app');
      assert.equal(result.possibility, 0);
    });

    it('handles invalid extractFrom indices', () => {
      const arbiter = setupChainRuleTestGraph();

      arbiter.setRelationConfig('invalid_extract', {
        type: 'chain',
        steps: [
          { relation: 'member_of', direction: 'out' },
          { relation: 'manages', direction: 'out' }
        ],
        extractValues: true,
        extractFrom: 10,  // Invalid index (only 2 steps)
        extractRelation: 'has_budget'
      });

      const result = arbiter.check('user:alice', 'invalid_extract', 'budget:tech-2024');

      // Should handle gracefully without crashing
      assert.ok(typeof result.possibility === 'number');
    });

    it('handles circular chain references', () => {
      const arbiter = setupChainRuleTestGraph();

      // Create a circular reference
      arbiter.addNode('node:a', 'node');
      arbiter.addNode('node:b', 'node');
      arbiter.addNode('node:c', 'node');

      arbiter.addRelation('node:a', 'connects_to', 'node:b');
      arbiter.addRelation('node:b', 'connects_to', 'node:c');
      arbiter.addRelation('node:c', 'connects_to', 'node:a');  // Circular

      arbiter.setRelationConfig('connects_to', { type: 'direct' });
      arbiter.setRelationConfig('circular_chain', {
        type: 'chain',
        steps: [
          { relation: 'connects_to', direction: 'out' },
          { relation: 'connects_to', direction: 'out' },
          { relation: 'connects_to', direction: 'out' }
        ]
      });

      const result = arbiter.check('node:a', 'circular_chain', 'node:a');

      // Should complete the circle
      assert.equal(result.possibility, 1);
    });

    it('validates step configuration correctness', () => {
      const arbiter = setupChainRuleTestGraph();

      // Test with malformed step configuration
      try {
        arbiter.setRelationConfig('malformed_chain', {
          type: 'chain',
          steps: [
            { relation: 'member_of' },  // Missing direction
            { direction: 'out' }        // Missing relation
          ]
        });

        const result = arbiter.check('user:alice', 'malformed_chain', 'project:web-app');

        // Should handle gracefully
        assert.equal(result.possibility, 0);
      } catch (error) {
        // Or might throw validation error - both acceptable
        assert.ok(error.message.includes('relation') || error.message.includes('direction'));
      }
    });
  });
});
