import { assertEntraConfig } from './check-entra-config';

const VALID = {
  ENTRA_INSTANCE_URL: 'https://login.microsoftonline.com/',
  ENTRA_TENANT_ID: 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
  ENTRA_CLIENT_ID: '11111111-2222-3333-4444-555555555555',
  ENTRA_CLIENT_SECRET: 's3cret-value-from-entra',
  ENTRA_REDIRECT_URI: 'http://localhost:3000/api/auth/callback',
  ENTRA_POST_LOGOUT_REDIRECT_URI: 'http://localhost:4200/',
  ENTRA_ADMIN_REDIRECT_URI: 'http://localhost:3000/api/admin/auth/callback',
  ENTRA_ADMIN_POST_LOGOUT_REDIRECT_URI: 'http://localhost:4300/',
};

describe('assertEntraConfig', () => {
  const originalEnv: Record<string, string | undefined> = {};

  beforeEach(() => {
    for (const key of Object.keys(VALID) as Array<keyof typeof VALID>) {
      originalEnv[key] = process.env[key];
      process.env[key] = VALID[key];
    }
  });

  afterEach(() => {
    for (const key of Object.keys(VALID) as Array<keyof typeof VALID>) {
      const saved = originalEnv[key];
      if (saved === undefined) {
        delete process.env[key];
      } else {
        process.env[key] = saved;
      }
    }
  });

  it('returns the parsed config when every key is present and well-formed', () => {
    const config = assertEntraConfig();
    expect(config.instanceUrl).toBe(VALID.ENTRA_INSTANCE_URL);
    expect(config.tenantId).toBe(VALID.ENTRA_TENANT_ID);
    expect(config.clientId).toBe(VALID.ENTRA_CLIENT_ID);
    expect(config.clientSecret).toBe(VALID.ENTRA_CLIENT_SECRET);
    expect(config.redirectUri).toBe(VALID.ENTRA_REDIRECT_URI);
    expect(config.postLogoutRedirectUri).toBe(VALID.ENTRA_POST_LOGOUT_REDIRECT_URI);
    expect(config.adminRedirectUri).toBe(VALID.ENTRA_ADMIN_REDIRECT_URI);
    expect(config.adminPostLogoutRedirectUri).toBe(VALID.ENTRA_ADMIN_POST_LOGOUT_REDIRECT_URI);
    expect(config.authority).toBe(`${VALID.ENTRA_INSTANCE_URL}${VALID.ENTRA_TENANT_ID}`);
  });

  it('throws when ENTRA_ADMIN_REDIRECT_URI equals ENTRA_REDIRECT_URI (would collapse the two surfaces)', () => {
    process.env['ENTRA_ADMIN_REDIRECT_URI'] = VALID.ENTRA_REDIRECT_URI;
    expect(() => assertEntraConfig()).toThrow(/must differ from ENTRA_REDIRECT_URI/);
  });

  it('rejects ENTRA_ADMIN_REDIRECT_URI when not a valid URL', () => {
    process.env['ENTRA_ADMIN_REDIRECT_URI'] = 'nope';
    expect(() => assertEntraConfig()).toThrow(/ENTRA_ADMIN_REDIRECT_URI is not a valid URL/);
  });

  it('throws listing every missing required key', () => {
    delete process.env['ENTRA_CLIENT_ID'];
    delete process.env['ENTRA_CLIENT_SECRET'];
    expect(() => assertEntraConfig()).toThrow(/ENTRA_CLIENT_ID, ENTRA_CLIENT_SECRET/);
  });

  it('throws when ENTRA_INSTANCE_URL is not https', () => {
    process.env['ENTRA_INSTANCE_URL'] = 'http://login.microsoftonline.com/';
    expect(() => assertEntraConfig()).toThrow(/ENTRA_INSTANCE_URL must use one of \[https:\]/);
  });

  it('throws when ENTRA_INSTANCE_URL is missing the trailing slash', () => {
    process.env['ENTRA_INSTANCE_URL'] = 'https://login.microsoftonline.com';
    expect(() => assertEntraConfig()).toThrow(/must end with a trailing "\/"/);
  });

  it('throws when ENTRA_TENANT_ID is not a UUID', () => {
    process.env['ENTRA_TENANT_ID'] = 'not-a-uuid';
    expect(() => assertEntraConfig()).toThrow(/ENTRA_TENANT_ID must be a UUID/);
  });

  it('throws when ENTRA_CLIENT_ID is still the .env.example placeholder', () => {
    process.env['ENTRA_CLIENT_ID'] = '00000000-0000-0000-0000-000000000000';
    expect(() => assertEntraConfig()).toThrow(/placeholder/);
  });

  it('throws when ENTRA_CLIENT_SECRET is still the .env.example placeholder', () => {
    process.env['ENTRA_CLIENT_SECRET'] = 'replace_with_real_value';
    expect(() => assertEntraConfig()).toThrow(/placeholder/);
  });

  it('accepts http for the redirect URIs (local dev case)', () => {
    process.env['ENTRA_REDIRECT_URI'] = 'http://localhost:3000/api/auth/callback';
    expect(() => assertEntraConfig()).not.toThrow();
  });

  it('rejects a redirect URI that is not a valid URL', () => {
    process.env['ENTRA_REDIRECT_URI'] = 'not-a-url';
    expect(() => assertEntraConfig()).toThrow(/ENTRA_REDIRECT_URI is not a valid URL/);
  });
});
