/**
 * Functional helpers for test environment management.
 * Returns new objects instead of mutating process.env directly.
 */

/**
 * Creates a new env object with specified overrides
 * @param {Record<string, string | undefined>} overrides - Env vars to set/override
 * @returns {Record<string, string>} New env object
 */
export const withEnv = overrides => ({
  ...process.env,
  ...Object.fromEntries(
    Object.entries(overrides).filter(([, v]) => v !== undefined),
  ),
})

/**
 * Creates a new env object with specified vars removed
 * @param {string[]} keys - Env var keys to remove
 * @returns {Record<string, string>} New env object
 */
export const withoutEnv = (keys) => {
  const result = { ...process.env }
  for (const key of keys) {
    delete result[key]
  }
  return result
}

/**
 * Executes a function with a temporary env, restoring original after
 * @param {Record<string, string | undefined>} env - Temporary env to use
 * @param {() => any} fn - Function to execute
 * @returns {any} Result of fn()
 */
export const withTemporaryEnv = (env, fn) => {
  const original = { ...process.env }
  try {
    // Set defined values
    Object.entries(env).forEach(([key, value]) => {
      if (value !== undefined) {
        process.env[key] = value
      }
      else {
        delete process.env[key]
      }
    })
    return fn()
  }
  finally {
    process.env = original
  }
}
