/**
 * Server management utilities for E2E tests.
 */

import { existsSync, mkdirSync } from 'node:fs'
import { join, dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
import { execSync } from 'node:child_process'

const _dirname = dirname(fileURLToPath(import.meta.url))
const projectRoot = join(_dirname, '../../..')
const devCertsDir = join(projectRoot, '.dev-certs')
const devKey = join(devCertsDir, 'key.pem')
const devCert = join(devCertsDir, 'cert.pem')

/**
 * Ensure .dev-certs directory exists and contains certificates.
 * Generates certs if missing (same logic as scripts/gen-dev-cert.sh).
 */
export function ensureDevCerts() {
  if (existsSync(devKey) && existsSync(devCert)) {
    return // Certs already exist
  }

  // Create .dev-certs directory
  mkdirSync(devCertsDir, { recursive: true })

  // Generate self-signed cert for localhost/127.0.0.1
  const SAN = 'subjectAltName=IP:127.0.0.1,DNS:localhost'
  try {
    execSync(
      `openssl req -x509 -newkey rsa:2048 -keyout "${devKey}" -out "${devCert}" -days 365 -nodes -subj "/CN=localhost" -addext "${SAN}"`,
      { cwd: projectRoot, stdio: 'inherit' },
    )
    console.log('[test] Generated .dev-certs/key.pem and .dev-certs/cert.pem')
  }
  catch (error) {
    throw new Error(`Failed to generate dev certificates: ${error.message}`, { cause: error })
  }
}

/**
 * Wait for server to be ready by polling the health endpoint.
 * @param {string} baseURL
 * @param {number} timeoutMs
 * @returns {Promise<void>}
 */
export async function waitForServerReady(baseURL = 'https://localhost:3000', timeoutMs = 120000) {
  const startTime = Date.now()
  const checkInterval = 1000 // Check every second

  while (Date.now() - startTime < timeoutMs) {
    try {
      const response = await fetch(`${baseURL}/health`, {
        method: 'GET',
        // @ts-ignore - ignoreHTTPSErrors is handled by Playwright context
      })
      if (response.ok) {
        return // Server is ready
      }
    }
    catch {
      // Server not ready yet, continue polling
    }
    await new Promise(resolve => setTimeout(resolve, checkInterval))
  }

  throw new Error(`Server did not become ready within ${timeoutMs}ms`)
}
