/**
 * fts5-snowball extension loader.
 *
 * Loads vendored fts5-snowball extension for multilingual FTS5 stemming.
 * Pattern mirrors sqlite-vec loader.
 *
 * @module src/store/sqlite/fts5-snowball
 */

import type { Database } from "bun:sqlite";

// node:fs: existsSync for sync file checks at load time
import { existsSync } from "node:fs";
// node:path: join for cross-platform paths
import { join } from "node:path";
// node:process: arch/platform detection (no Bun equivalent)
import { arch, platform } from "node:process";
import { fileURLToPath } from "node:url";

// ─────────────────────────────────────────────────────────────────────────────
// Types
// ─────────────────────────────────────────────────────────────────────────────

/**
 * Result of attempting to load fts5-snowball.
 */
export interface Fts5SnowballLoadResult {
  loaded: boolean;
  error?: string;
  path?: string;
}

// ─────────────────────────────────────────────────────────────────────────────
// Platform Detection
// ─────────────────────────────────────────────────────────────────────────────

function getPlatformDir(): string | null {
  const os = platform === "win32" ? "windows" : platform;
  const archName = arch === "arm64" ? "arm64" : "x64";

  if (os === "darwin") {
    return `darwin-${archName}`;
  }
  if (os === "linux" && archName === "x64") {
    return "linux-x64";
  }
  if (os === "windows" && archName === "x64") {
    return "windows-x64";
  }

  return null;
}

function getExtensionSuffix(): string {
  if (platform === "win32") {
    return "dll";
  }
  if (platform === "darwin") {
    return "dylib";
  }
  return "so";
}

// ─────────────────────────────────────────────────────────────────────────────
// Path Resolution
// ─────────────────────────────────────────────────────────────────────────────

/**
 * Get path to vendored fts5-snowball extension.
 * Returns null if not available for this platform.
 */
export function getExtensionPath(): string | null {
  const platformDir = getPlatformDir();
  if (!platformDir) {
    return null;
  }

  const suffix = getExtensionSuffix();
  const filename = `fts5stemmer.${suffix}`;

  // Resolve relative to this module (ESM-safe)
  const thisDir = fileURLToPath(new URL(".", import.meta.url));
  const vendorPath = join(
    thisDir,
    "..",
    "..",
    "..",
    "vendor",
    "fts5-snowball",
    platformDir,
    filename
  );

  if (existsSync(vendorPath)) {
    return vendorPath;
  }

  return null;
}

// ─────────────────────────────────────────────────────────────────────────────
// Extension Loading
// ─────────────────────────────────────────────────────────────────────────────

/**
 * Load fts5-snowball extension into database.
 *
 * Must be called after Database.setCustomSQLite() on macOS.
 * Safe to call multiple times - extension load is idempotent.
 *
 * @param db - Open database connection
 * @returns Load result with success/error info
 */
export function loadFts5Snowball(db: Database): Fts5SnowballLoadResult {
  const path = getExtensionPath();

  if (!path) {
    const platformDir = getPlatformDir();
    return {
      loaded: false,
      error: platformDir
        ? `fts5-snowball binary not found for ${platformDir}`
        : `fts5-snowball not available for ${platform}-${arch}`,
    };
  }

  try {
    db.loadExtension(path);
    return { loaded: true, path };
  } catch (e) {
    const message = e instanceof Error ? e.message : String(e);
    return {
      loaded: false,
      error: message,
      path,
    };
  }
}

/**
 * Check if fts5-snowball is available for this platform.
 */
export function isAvailable(): boolean {
  return getExtensionPath() !== null;
}
