// Préparation d'un environnement d'authentification git ÉPHÉMÈRE (P12). HTTPS (pat/app_password) :
// les identifiants sont fournis via GIT_ASKPASS (script 0o700 lisant deux variables d'env), JAMAIS
// dans l'URL ni dans `.git/config`. GIT_TERMINAL_PROMPT=0 (pas d'invite bloquante). Le script est
// supprimé en `finally` ; le secret ne transite que par l'env du process enfant (jamais loggé).
import { mkdtemp, writeFile, rm, chmod } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import type { GitService } from '@arboretum/shared';
import type { GitAuth } from './git-clients/index.js';

// Identité HTTPS par défaut quand l'utilisateur n'a pas fourni de username (token-as-password).
const SERVICE_DEFAULT_USER: Record<GitService, string> = { github: 'x-access-token', gitlab: 'oauth2', gitea: 'oauth2' };

export async function withGitAuth<T>(
  service: GitService,
  auth: GitAuth,
  fn: (env: NodeJS.ProcessEnv) => Promise<T>,
): Promise<T> {
  const dir = await mkdtemp(join(tmpdir(), 'arb-gitauth-'));
  const askpass = join(dir, 'askpass.sh');
  const user = auth.username || SERVICE_DEFAULT_USER[service];
  await writeFile(
    askpass,
    "#!/bin/sh\ncase \"$1\" in\n  Username*) printf '%s' \"$ARB_GIT_USER\" ;;\n  *) printf '%s' \"$ARB_GIT_PASS\" ;;\nesac\n",
    { mode: 0o700 },
  );
  await chmod(askpass, 0o700);
  const env: NodeJS.ProcessEnv = {
    ...process.env,
    GIT_ASKPASS: askpass,
    GIT_TERMINAL_PROMPT: '0',
    ARB_GIT_USER: user,
    ARB_GIT_PASS: auth.secret,
  };
  try {
    return await fn(env);
  } finally {
    await rm(dir, { recursive: true, force: true }).catch(() => {});
  }
}
