"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var ocaml_exports = {};
__export(ocaml_exports, {
  ocamlParser: () => ocamlParser
});
module.exports = __toCommonJS(ocaml_exports);
var fs = __toESM(require("fs"));
var path = __toESM(require("path"));
const ocamlParser = {
  name: "ocaml",
  manifestFiles: ["dune-project"],
  language: "ocaml",
  canParse(manifestPath) {
    const base = path.basename(manifestPath);
    return base === "dune-project" || base.endsWith(".opam");
  },
  async parse(manifestPath, projectRoot) {
    let content;
    try {
      content = fs.readFileSync(manifestPath, "utf8");
    } catch {
      return [];
    }
    const relDir = path.relative(projectRoot, path.dirname(manifestPath)).replace(/\\/g, "/") || ".";
    const relManifest = path.relative(projectRoot, manifestPath).replace(/\\/g, "/");
    const base = path.basename(manifestPath);
    if (base === "dune-project") {
      return parseDuneProject(content, relDir, relManifest, projectRoot, manifestPath);
    }
    return parseOpam(content, base, relDir, relManifest);
  }
};
function parseDuneProject(content, relDir, relManifest, projectRoot, manifestPath) {
  const packages = [];
  const nameMatch = content.match(/\(name\s+([^\s)]+)\)/);
  const name = nameMatch ? nameMatch[1] : path.basename(path.dirname(manifestPath));
  const versionMatch = content.match(/\(version\s+([^\s)]+)\)/);
  const version = versionMatch ? versionMatch[1] : void 0;
  const externalDeps = [];
  const dependsMatch = content.match(/\(depends([\s\S]*?)\)(?:\s*\(|$)/);
  if (dependsMatch) {
    const depPattern = /\(([a-zA-Z0-9_-]+)[\s)]/g;
    const bareDep = /^\s+([a-zA-Z0-9_-]+)\s*$/gm;
    let m;
    while ((m = depPattern.exec(dependsMatch[1])) !== null) {
      if (m[1] !== "and" && m[1] !== "or") externalDeps.push(m[1]);
    }
    while ((m = bareDep.exec(dependsMatch[1])) !== null) {
      externalDeps.push(m[1]);
    }
  }
  packages.push({
    id: `pkg:ocaml:${relDir}`,
    name,
    path: relDir,
    source: "manifest",
    language: "ocaml",
    manifestPath: relManifest,
    version,
    externalDeps,
    updatedAt: Date.now()
  });
  const duneDir = path.dirname(path.join(projectRoot, relManifest));
  const subDirs = findDuneLibraries(duneDir, projectRoot);
  for (const sub of subDirs) {
    if (sub.path !== relDir) {
      packages.push({
        id: `pkg:ocaml:${sub.path}`,
        name: sub.name,
        path: sub.path,
        source: "manifest",
        language: "ocaml",
        manifestPath: relManifest,
        updatedAt: Date.now()
      });
    }
  }
  return packages;
}
function parseOpam(content, filename, relDir, relManifest) {
  const name = filename.replace(".opam", "");
  const versionMatch = content.match(/^version:\s*"([^"]+)"/m);
  const version = versionMatch ? versionMatch[1] : void 0;
  const externalDeps = [];
  const dependsMatch = content.match(/^depends:\s*\[([\s\S]*?)\]/m);
  if (dependsMatch) {
    const depPattern = /"([a-zA-Z0-9_-]+)"/g;
    let m;
    while ((m = depPattern.exec(dependsMatch[1])) !== null) {
      externalDeps.push(m[1]);
    }
  }
  return [{
    id: `pkg:ocaml:${relDir}:${name}`,
    name,
    path: relDir,
    source: "manifest",
    language: "ocaml",
    manifestPath: relManifest,
    version,
    externalDeps,
    updatedAt: Date.now()
  }];
}
function findDuneLibraries(dir, projectRoot) {
  const results = [];
  const skipDirs = /* @__PURE__ */ new Set(["_build", ".git", "node_modules", "_opam"]);
  function walk(currentDir) {
    let entries;
    try {
      entries = fs.readdirSync(currentDir, { withFileTypes: true });
    } catch {
      return;
    }
    for (const entry of entries) {
      if (entry.isDirectory() && !skipDirs.has(entry.name)) {
        walk(path.join(currentDir, entry.name));
      } else if (entry.isFile() && entry.name === "dune") {
        const dunePath = path.join(currentDir, "dune");
        try {
          const duneContent = fs.readFileSync(dunePath, "utf8");
          const libMatch = duneContent.match(/\(library[\s\S]*?\(name\s+([^\s)]+)\)/);
          if (libMatch) {
            const relPath = path.relative(projectRoot, currentDir).replace(/\\/g, "/");
            results.push({ name: libMatch[1], path: relPath });
          }
        } catch {
        }
      }
    }
  }
  walk(dir);
  return results;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  ocamlParser
});
//# sourceMappingURL=ocaml.js.map
