/**
 * Minimal .env file reader/writer for the `madarx setup` wizard.
 *
 * Upsert semantics: replace an existing `KEY=` line in place, otherwise append.
 * Writes mode 600 — the file holds the secrets-vault master key and other
 * credentials. Pure string logic (no env mutation) so it's unit-testable.
 *
 * NOTE: the master key is owned by lib/master-key.js (which refuses to append a
 * second MADARX_MASTER_KEY). The wizard never routes the master key through
 * upsertEnvVar — only non-secret config (allowed roots, WhatsApp toggle, etc.).
 */

import fs from 'node:fs';
import path from 'node:path';

function escapeRe(s) {
  return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

function readRaw(file) {
  try {
    return fs.readFileSync(file, 'utf8');
  } catch (err) {
    if (err.code === 'ENOENT') return '';
    throw err;
  }
}

/** Parse an env file into a plain object. Ignores comments and blank lines. */
export function readEnvFile(file) {
  const out = {};
  for (const line of readRaw(file).split('\n')) {
    const t = line.trim();
    if (!t || t.startsWith('#')) continue;
    const eq = t.indexOf('=');
    if (eq <= 0) continue;
    const key = t.slice(0, eq).trim();
    const val = t.slice(eq + 1).trim().replace(/^["']|["']$/g, '');
    out[key] = val;
  }
  return out;
}

/**
 * Insert or replace KEY=value. Returns the written file content. Creates the
 * parent directory and the file (mode 600) if missing.
 */
export function upsertEnvVar(file, key, value) {
  const content = readRaw(file);
  const lines = content === '' ? [] : content.split('\n');
  const re = new RegExp(`^\\s*${escapeRe(key)}\\s*=`);
  let found = false;
  const next = lines.map((line) => {
    if (re.test(line)) { found = true; return `${key}=${value}`; }
    return line;
  });
  if (!found) {
    while (next.length && next[next.length - 1] === '') next.pop();
    if (next.length) next.push('');
    next.push(`${key}=${value}`);
  }
  let out = next.join('\n').replace(/\n{3,}/g, '\n\n');
  if (!out.endsWith('\n')) out += '\n';
  fs.mkdirSync(path.dirname(file), { recursive: true });
  fs.writeFileSync(file, out, { mode: 0o600 });
  try { fs.chmodSync(file, 0o600); } catch {}
  return out;
}

/** Remove a KEY= line if present. No-op when the file or key is absent. */
export function removeEnvVar(file, key) {
  const content = readRaw(file);
  if (content === '') return;
  const re = new RegExp(`^\\s*${escapeRe(key)}\\s*=`);
  const next = content.split('\n').filter((line) => !re.test(line));
  let out = next.join('\n').replace(/\n{3,}/g, '\n\n');
  if (out !== '' && !out.endsWith('\n')) out += '\n';
  fs.writeFileSync(file, out, { mode: 0o600 });
  try { fs.chmodSync(file, 0o600); } catch {}
}
