import { describe, it, expect } from 'vitest';
import { isDelegationLive, resolveEffectiveSpaces, resolveEffectiveSkills } from './delegation.js';

describe('a2a delegation AND-intersection', () => {
  it('isDelegationLive: false when revoked or expired', () => {
    expect(isDelegationLive({ expiresAt: null, revokedAt: null }, '2026-06-27T00:00:00Z')).toBe(true);
    expect(isDelegationLive({ expiresAt: null, revokedAt: '2026-06-26T00:00:00Z' }, '2026-06-27T00:00:00Z')).toBe(false);
    expect(isDelegationLive({ expiresAt: '2026-06-26T00:00:00Z', revokedAt: null }, '2026-06-27T00:00:00Z')).toBe(false);
    expect(isDelegationLive({ expiresAt: '2026-06-28T00:00:00Z', revokedAt: null }, '2026-06-27T00:00:00Z')).toBe(true);
  });

  it('isDelegationLive: boundary case when expiresAt equals nowIso', () => {
    expect(isDelegationLive({ expiresAt: '2026-06-27T00:00:00Z', revokedAt: null }, '2026-06-27T00:00:00Z')).toBe(false);
  });

  it('isDelegationLive: non-UTC offset comparison (Important fix)', () => {
    // expiresAt with +05:00 offset: 2026-06-27T02:00:00+05:00 = 2026-06-26T21:00:00Z
    // nowIso in Z: 2026-06-27T00:00:00Z
    // expiresAt (21:00Z) < nowIso (00:00Z on next day) → expired
    expect(isDelegationLive({ expiresAt: '2026-06-27T02:00:00+05:00', revokedAt: null }, '2026-06-27T00:00:00Z')).toBe(false);
  });

  it('resolveEffectiveSpaces: intersection only (no grant of unseen space)', () => {
    expect(resolveEffectiveSpaces(['s1', 's2', 's3'], ['s2', 's3', 's9'])).toEqual(['s2', 's3']);
    expect(resolveEffectiveSpaces(['s1'], ['s2'])).toEqual([]); // out-of-scope → empty (fail-closed)
  });

  it('resolveEffectiveSpaces: empty-input fail-closed', () => {
    expect(resolveEffectiveSpaces([], ['s2'])).toEqual([]);
    expect(resolveEffectiveSpaces(['s1'], [])).toEqual([]);
  });

  it('resolveEffectiveSpaces: deduplication of grantedSpaceIds', () => {
    expect(resolveEffectiveSpaces(['s1', 's1'], ['s1'])).toEqual(['s1']);
    expect(resolveEffectiveSpaces(['s1', 's1', 's2', 's2'], ['s1', 's2'])).toEqual(['s1', 's2']);
  });

  it('resolveEffectiveSkills: granted ∩ union of allowlists of effective spaces', () => {
    const allow = { s2: ['research', 'summarize'], s3: ['translate'], s9: ['admin'] };
    // effective spaces s2,s3; granted skills research,translate,admin
    expect(resolveEffectiveSkills(['research', 'translate', 'admin'], allow, ['s2', 's3']).sort())
      .toEqual(['research', 'translate']); // admin only allowed in s9 which is not effective
  });

  it('resolveEffectiveSkills: empty when no effective spaces', () => {
    expect(resolveEffectiveSkills(['research'], { s1: ['research'] }, [])).toEqual([]);
  });

  it('resolveEffectiveSkills: reverse exclusion (skill in allowlist but not in grantedSkills)', () => {
    // grantedSkills: ['research']
    // s1 allowlist: ['research', 'summarize']
    // effective spaces: ['s1']
    // result: only 'research' (because 'summarize' is not granted)
    const allow = { s1: ['research', 'summarize'] };
    expect(resolveEffectiveSkills(['research'], allow, ['s1']).sort()).toEqual(['research']);
  });
});
