#!/usr/bin/env node

const fs = require('node:fs')
const path = require('node:path')
const { spawn } = require('node:child_process')

function parseEnvFile(content) {
  const env = {}

  for (const rawLine of content.split(/\r?\n/)) {
    const line = rawLine.trim()
    if (!line || line.startsWith('#')) continue

    const normalized = line.startsWith('export ') ? line.slice(7).trim() : line
    const separatorIndex = normalized.indexOf('=')
    if (separatorIndex === -1) continue

    const key = normalized.slice(0, separatorIndex).trim()
    if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) continue

    let value = normalized.slice(separatorIndex + 1)

    if (
      (value.startsWith('"') && value.endsWith('"')) ||
      (value.startsWith("'") && value.endsWith("'"))
    ) {
      const quote = value[0]
      value = value.slice(1, -1)

      if (quote === '"') {
        value = value
          .replace(/\\n/g, '\n')
          .replace(/\\r/g, '\r')
          .replace(/\\t/g, '\t')
          .replace(/\\"/g, '"')
          .replace(/\\\\/g, '\\')
      }
    }

    env[key] = value
  }

  return env
}

const [, , envFileArg, commandArg, ...commandArgs] = process.argv

if (!envFileArg || !commandArg) {
  console.error('Usage: node run-with-env-file.cjs <env-file> <command> [args...]')
  process.exit(1)
}

const envFilePath = path.resolve(process.cwd(), envFileArg)
const commandPath = path.resolve(process.cwd(), commandArg)
const fileContent = fs.readFileSync(envFilePath, 'utf8')
const parsedEnv = parseEnvFile(fileContent)

const child = spawn(commandPath, commandArgs, {
  stdio: 'inherit',
  env: {
    ...process.env,
    ...parsedEnv,
  },
})

child.on('exit', (code, signal) => {
  if (signal) {
    process.kill(process.pid, signal)
    return
  }

  process.exit(code ?? 0)
})

child.on('error', (error) => {
  console.error(error.message)
  process.exit(1)
})
