import { describe, expect, it } from 'vitest';

import { mkdtempSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import path from 'node:path';

import { getSupabaseJwtRole, resolveSupabaseKey, resolveSupabaseTlsConfig, resolveSupabaseUrl } from './supabase-env.ts';

function createJwt(role: string) {
  const header = Buffer.from(JSON.stringify({ alg: 'HS256', typ: 'JWT' })).toString('base64url');
  const payload = Buffer.from(JSON.stringify({ role })).toString('base64url');
  return `${header}.${payload}.signature`;
}

describe('supabase-env', () => {
  it('reads the JWT role claim', () => {
    expect(getSupabaseJwtRole(createJwt('service_role'))).toBe('service_role');
    expect(getSupabaseJwtRole(createJwt('anon'))).toBe('anon');
    expect(getSupabaseJwtRole('bad-token')).toBe('');
  });

  it('prefers a real service_role key over an anon key', () => {
    expect(resolveSupabaseKey({
      SUPABASE_SERVICE_ROLE_KEY: createJwt('anon'),
      VITE_SUPABASE_SERVICE_ROLE_KEY: createJwt('service_role'),
      SUPABASE_ANON_KEY: createJwt('anon'),
    } as NodeJS.ProcessEnv)).toBe(createJwt('service_role'));
  });

  it('falls back to the first available key when no service role key exists', () => {
    expect(resolveSupabaseKey({
      SUPABASE_SERVICE_ROLE_KEY: createJwt('anon'),
      SUPABASE_ANON_KEY: createJwt('anon'),
    } as NodeJS.ProcessEnv)).toBe(createJwt('anon'));
  });

  it('resolves the Supabase URL from server or Vite env', () => {
    expect(resolveSupabaseUrl({ SUPABASE_URL: 'https://server.example.co' } as NodeJS.ProcessEnv)).toBe('https://server.example.co');
    expect(resolveSupabaseUrl({ VITE_SUPABASE_URL: 'https://vite.example.co' } as NodeJS.ProcessEnv)).toBe('https://vite.example.co');
  });

  it('normalizes inline CA certificates from env', () => {
    expect(resolveSupabaseTlsConfig({
      SUPABASE_TLS_CA_CERT: '-----BEGIN CERTIFICATE-----\\nTEST\\n-----END CERTIFICATE-----',
    } as NodeJS.ProcessEnv)).toEqual({
      ca: '-----BEGIN CERTIFICATE-----\nTEST\n-----END CERTIFICATE-----',
      rejectUnauthorized: true,
    });
  });

  it('reads CA certificates from a file path', () => {
    const tempDir = mkdtempSync(path.join(tmpdir(), 'supabase-ca-'));
    const certPath = path.join(tempDir, 'ca.pem');
    writeFileSync(certPath, '-----BEGIN CERTIFICATE-----\nFILE\n-----END CERTIFICATE-----\n');

    expect(resolveSupabaseTlsConfig({
      SUPABASE_TLS_CA_CERT_PATH: certPath,
    } as NodeJS.ProcessEnv)).toEqual({
      ca: '-----BEGIN CERTIFICATE-----\nFILE\n-----END CERTIFICATE-----',
      rejectUnauthorized: true,
    });
  });

  it('supports an explicit insecure skip-verify switch', () => {
    expect(resolveSupabaseTlsConfig({
      SUPABASE_TLS_INSECURE_SKIP_VERIFY: '1',
    } as NodeJS.ProcessEnv)).toEqual({
      ca: undefined,
      rejectUnauthorized: false,
    });
  });
});