/**
 * Downloads the appropriate ripgrep binary from GitHub releases into
 * src/utils/vendor/ripgrep/<platform>/ so that Glob and Grep tools work
 * without requiring a system-wide ripgrep install.
 *
 * Runs via npm postinstall. Uses Node built-ins only (no dependencies).
 * Skips download if the binary already exists.
 *
 * CommonJS so it works reliably during npm install -g (no ESM loader issues).
 */
const {
  cpSync,
  createWriteStream,
  existsSync,
  mkdirSync,
  rmSync,
  unlinkSync,
} = require('fs');
const { join, resolve } = require('path');
const { pipeline } = require('stream/promises');
const { execFileSync } = require('child_process');
const { Readable } = require('stream');

const root = resolve(__dirname, '..');

const RIPGREP_VERSION = '14.1.0';

const PLATFORM_MAP = {
  'win32-x64': {
    archive: `ripgrep-${RIPGREP_VERSION}-x86_64-pc-windows-msvc.zip`,
    binary: 'rg.exe',
    subdir: `ripgrep-${RIPGREP_VERSION}-x86_64-pc-windows-msvc`,
    extract: 'zip',
  },
  'darwin-x64': {
    archive: `ripgrep-${RIPGREP_VERSION}-x86_64-apple-darwin.tar.gz`,
    binary: 'rg',
    subdir: `ripgrep-${RIPGREP_VERSION}-x86_64-apple-darwin`,
    extract: 'tar',
  },
  'darwin-arm64': {
    archive: `ripgrep-${RIPGREP_VERSION}-aarch64-apple-darwin.tar.gz`,
    binary: 'rg',
    subdir: `ripgrep-${RIPGREP_VERSION}-aarch64-apple-darwin`,
    extract: 'tar',
  },
  'linux-x64': {
    archive: `ripgrep-${RIPGREP_VERSION}-x86_64-unknown-linux-musl.tar.gz`,
    binary: 'rg',
    subdir: `ripgrep-${RIPGREP_VERSION}-x86_64-unknown-linux-musl`,
    extract: 'tar',
  },
  'linux-arm64': {
    archive: `ripgrep-${RIPGREP_VERSION}-aarch64-unknown-linux-musl.tar.gz`,
    binary: 'rg',
    subdir: `ripgrep-${RIPGREP_VERSION}-aarch64-unknown-linux-musl`,
    extract: 'tar',
  },
};

function getVendorDir() {
  const platformDir =
    process.platform === 'win32'
      ? `${process.arch}-win32`
      : `${process.arch}-${process.platform}`;
  return join(root, 'src', 'utils', 'vendor', 'ripgrep', platformDir);
}

async function downloadFile(url, destPath) {
  const response = await fetch(url);
  if (!response.ok) {
    throw new Error(`Failed to download ${url}: HTTP ${response.status}`);
  }
  const fileStream = createWriteStream(destPath);
  const nodeStream = Readable.fromWeb(response.body);
  await pipeline(nodeStream, fileStream);
}

function extractZip(archivePath, destDir, subdir, binaryName) {
  execFileSync('powershell', [
    '-NoProfile',
    '-Command',
    `Expand-Archive -Path "${archivePath}" -DestinationPath "${destDir}" -Force`,
  ]);

  const extracted = join(destDir, subdir, binaryName);
  const target = join(destDir, binaryName);
  if (existsSync(extracted) && extracted !== target) {
    cpSync(extracted, target, { force: true });
  }
}

function extractTar(archivePath, destDir, subdir, binaryName) {
  execFileSync('tar', ['-xzf', archivePath, '-C', destDir]);

  const extracted = join(destDir, subdir, binaryName);
  const target = join(destDir, binaryName);
  if (existsSync(extracted) && extracted !== target) {
    cpSync(extracted, target, { force: true });
  }
}

async function main() {
  const platformKey = `${process.platform}-${process.arch}`;
  const config = PLATFORM_MAP[platformKey];

  if (!config) {
    console.warn(
      `[download-ripgrep] Unsupported platform: ${platformKey}. Skipping ripgrep download.`,
    );
    return;
  }

  const vendorDir = getVendorDir();
  const binaryPath = join(vendorDir, config.binary);

  if (existsSync(binaryPath)) {
    console.warn(`[download-ripgrep] Binary already exists at ${binaryPath}`);
    return;
  }

  mkdirSync(vendorDir, { recursive: true });

  const url = `https://github.com/BurntSushi/ripgrep/releases/download/${RIPGREP_VERSION}/${config.archive}`;
  const archivePath = join(vendorDir, config.archive);

  console.warn(`[download-ripgrep] Downloading ${config.archive}...`);

  try {
    await downloadFile(url, archivePath);
    console.warn(`[download-ripgrep] Extracting ${config.binary}...`);

    if (config.extract === 'zip') {
      extractZip(archivePath, vendorDir, config.subdir, config.binary);
    } else {
      extractTar(archivePath, vendorDir, config.subdir, config.binary);
    }

    try {
      unlinkSync(archivePath);
    } catch {
      // Ignore cleanup failure
    }

    const subdirPath = join(vendorDir, config.subdir);
    try {
      if (existsSync(subdirPath)) {
        rmSync(subdirPath, { recursive: true, force: true });
      }
    } catch {
      // Ignore cleanup failure
    }

    console.warn(`[download-ripgrep] Installed ripgrep to ${binaryPath}`);
  } catch (err) {
    console.warn(
      `[download-ripgrep] Failed to download ripgrep: ${err.message}`,
    );
    console.warn(
      `[download-ripgrep] Glob/Grep tools will need system ripgrep on PATH.`,
    );
  }
}

main().catch((err) => {
  console.warn(`[download-ripgrep] Unexpected error: ${err.message}`);
});
