import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
import { coalesce } from './coalesce.js';

const execFileP = promisify(execFile);
const SITE_DIR = process.env.SITE_DIR || '/site';

// Baut die Site. dest ist relativ zum Repo-Root (z.B. "public" oder "preview").
// drafts:true => --buildDrafts (für die Vorschau).
export async function hugoBuild({ dest, drafts = false } = {}) {
  const args = ['--source', SITE_DIR, '--destination', dest, '--cleanDestinationDir'];
  if (drafts) args.push('--buildDrafts');
  const { stdout, stderr } = await execFileP('hugo', args, {
    cwd: SITE_DIR,
    maxBuffer: 10 * 1024 * 1024,
  });
  return { stdout, stderr };
}

// Koaleszierter Build je Ziel: nie zwei `hugo`-Prozesse für dasselbe dest
// parallel; schnelle Folge-Aufrufe lösen nur einen nachgelagerten Build aus.
// Publish (public), Preview (preview) und Profil teilen sich diesen Weg.
export function buildSite({ dest, drafts = false } = {}) {
  return coalesce(`build:${dest}:${drafts ? 'd' : 'p'}`, () => hugoBuild({ dest, drafts }));
}

// Optionaler Git-Backup beim Publish (GIT_PUBLISH=true). Schlägt nie hart fehl —
// das Publish soll an einem Git-Problem nicht scheitern.
export async function gitCommit(message) {
  if (process.env.GIT_PUBLISH !== 'true') return { skipped: true };

  const env = {
    ...process.env,
    GIT_AUTHOR_NAME: process.env.GIT_AUTHOR_NAME || 'OPENBUREAU CMS',
    GIT_AUTHOR_EMAIL: process.env.GIT_AUTHOR_EMAIL || 'cms@openbureau.ch',
    GIT_COMMITTER_NAME: process.env.GIT_AUTHOR_NAME || 'OPENBUREAU CMS',
    GIT_COMMITTER_EMAIL: process.env.GIT_AUTHOR_EMAIL || 'cms@openbureau.ch',
  };
  const git = (...args) => execFileP('git', ['-C', SITE_DIR, ...args], { env });

  await git('add', 'content');
  // Nichts zu committen? Dann ruhig raus.
  const status = await git('status', '--porcelain', 'content');
  if (!status.stdout.trim()) return { nothing: true };

  await git('commit', '-m', message);
  await git('push', process.env.GIT_REMOTE || 'origin', process.env.GIT_BRANCH || 'main');
  return { committed: true };
}
