import { describe, expect, it } from 'vitest';
import { seedId, seedUuid, stableUuidFromSeedKey } from './SeedIdHelper';

describe('SeedIdHelper', () => {
  describe('stableUuidFromSeedKey', () => {
    it('should return a valid UUID v4 format', () => {
      const uuid = stableUuidFromSeedKey('team-3');
      
      // UUID v4 format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
      // where y is one of [8, 9, a, b]
      const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
      expect(uuid).toMatch(uuidRegex);
    });

    it('should be deterministic - same input produces same output', () => {
      const input = 'driver-1';
      const uuid1 = stableUuidFromSeedKey(input);
      const uuid2 = stableUuidFromSeedKey(input);
      
      expect(uuid1).toBe(uuid2);
    });

    it('should produce different UUIDs for different inputs', () => {
      const uuid1 = stableUuidFromSeedKey('team-1');
      const uuid2 = stableUuidFromSeedKey('team-2');
      
      expect(uuid1).not.toBe(uuid2);
    });

    it('should handle various seed patterns', () => {
      const testCases = [
        'team-3',
        'driver-1',
        'league-5',
        'race-10',
        'sponsor-1',
        'season-1',
        'demo-sponsor-1',
        'league-3-season-a',
        'team-join-team-1-driver-5',
        'dup-team-join-req-1',
      ];

      testCases.forEach((seed) => {
        const uuid = stableUuidFromSeedKey(seed);
        const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
        expect(uuid).toMatch(uuidRegex);
        expect(uuid.length).toBe(36);
      });
    });

    it('should handle empty string', () => {
      const uuid = stableUuidFromSeedKey('');
      const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
      expect(uuid).toMatch(uuidRegex);
    });

    it('should handle long seed strings', () => {
      const longSeed = 'a'.repeat(1000);
      const uuid = stableUuidFromSeedKey(longSeed);
      const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
      expect(uuid).toMatch(uuidRegex);
    });
  });

  describe('seedId', () => {
    it('should return UUID for postgres mode', () => {
      const result = seedId('team-3', 'postgres');
      const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
      expect(result).toMatch(uuidRegex);
    });

    it('should return original string for inmemory mode', () => {
      const result = seedId('team-3', 'inmemory');
      expect(result).toBe('team-3');
    });

    it('should be deterministic for postgres mode', () => {
      const result1 = seedId('driver-5', 'postgres');
      const result2 = seedId('driver-5', 'postgres');
      expect(result1).toBe(result2);
    });

    it('should preserve original string for inmemory mode', () => {
      const testCases = ['team-3', 'driver-1', 'league-5', 'race-10'];
      
      testCases.forEach((seed) => {
        const result = seedId(seed, 'inmemory');
        expect(result).toBe(seed);
      });
    });
  });

  describe('seedUuid', () => {
    it('should return a valid UUID', () => {
      const uuid = seedUuid('team-3');
      const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
      expect(uuid).toMatch(uuidRegex);
    });

    it('should be deterministic', () => {
      const uuid1 = seedUuid('driver-1');
      const uuid2 = seedUuid('driver-1');
      expect(uuid1).toBe(uuid2);
    });

    it('should produce different UUIDs for different inputs', () => {
      const uuid1 = seedUuid('team-1');
      const uuid2 = seedUuid('team-2');
      expect(uuid1).not.toBe(uuid2);
    });
  });

  describe('UUID v4 compliance', () => {
    it('should have version 4 bits set correctly', () => {
      const uuid = stableUuidFromSeedKey('test');
      // Version is in the 13th character (0-indexed), should be '4'
      expect(uuid.charAt(14)).toBe('4');
    });

    it('should have variant bits set correctly', () => {
      const uuid = stableUuidFromSeedKey('test');
      // Variant is in the 19th character (0-indexed), should be 8, 9, a, or b
      const variantChar = uuid.charAt(19);
      expect(['8', '9', 'a', 'b']).toContain(variantChar.toLowerCase());
    });
  });
});