import { describe, it, expect, beforeEach } from 'vitest';
import { AuthManager, generatePassphrase } from '../../src/server/auth.js';

describe('AuthManager', () => {
  let auth: AuthManager;

  beforeEach(async () => {
    auth = new AuthManager();
    await auth.setPassword('test-password');
  });

  describe('password verification', () => {
    it('accepts correct password', async () => {
      expect(await auth.verifyPassword('test-password')).toBe(true);
    });

    it('rejects wrong password', async () => {
      expect(await auth.verifyPassword('wrong')).toBe(false);
    });
  });

  describe('JWT tokens', () => {
    it('generates and verifies a valid token', () => {
      const token = auth.generateToken();
      expect(auth.verifyToken(token)).toBe(true);
    });

    it('rejects invalid tokens', () => {
      expect(auth.verifyToken('not-a-real-token')).toBe(false);
    });

    it('rejects tokens from different instance', async () => {
      const token = auth.generateToken();
      const other = new AuthManager();
      await other.setPassword('x');
      expect(other.verifyToken(token)).toBe(false);
    });
  });

  describe('rate limiting', () => {
    it('allows initial attempts', () => {
      expect(auth.isRateLimited('1.2.3.4')).toBe(false);
    });

    it('blocks after max attempts', () => {
      for (let i = 0; i < 5; i++) {
        auth.recordAttempt('1.2.3.4');
      }
      expect(auth.isRateLimited('1.2.3.4')).toBe(true);
    });

    it('does not affect other IPs', () => {
      for (let i = 0; i < 5; i++) {
        auth.recordAttempt('1.2.3.4');
      }
      expect(auth.isRateLimited('5.6.7.8')).toBe(false);
    });

    it('resets after successful auth', () => {
      for (let i = 0; i < 3; i++) {
        auth.recordAttempt('1.2.3.4');
      }
      auth.resetAttempts('1.2.3.4');
      expect(auth.isRateLimited('1.2.3.4')).toBe(false);
    });
  });
});

describe('generatePassphrase', () => {
  it('generates a 4-word passphrase', () => {
    const phrase = generatePassphrase();
    const words = phrase.split('-');
    expect(words.length).toBe(4);
    for (const word of words) {
      expect(word.length).toBeGreaterThan(0);
    }
  });

  it('generates different passphrases', () => {
    const a = generatePassphrase();
    const b = generatePassphrase();
    // Extremely unlikely to be equal
    expect(a).not.toBe(b);
  });
});
