"use strict";
/* Socket Lib - Built with rolldown */
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_primordials_string = require('../../primordials/string.js');
const require_primordials_array = require('../../primordials/array.js');
const require_primordials_object = require('../../primordials/object.js');

//#region src/eco/cargo/parse-lockfile.ts
/**
* @file `parseCargoLock(content)` — parses a Rust `Cargo.lock` (v1/v2/v3/v4)
*   into a `ParsedLockfile`. Cargo.lock uses a constrained TOML dialect: a
*   top-level `version = N` scalar plus repeating `[[package]]` array-of-table
*   entries. We line-scan it instead of pulling in a full TOML parser — the
*   spec for the lockfile is stable and small (`name`, `version`, `source`,
*   `checksum`, `dependencies = [ ... ]`), and a hand-rolled scanner is ~100×
*   cheaper than dragging in `@iarna/toml` for one use case. `dependencies`
*   entries come in two forms (cargo strips redundant versions when they're
*   unambiguous):
*
*   - `"name 1.2.3"` — name + space-separated version
*   - `"name"` — name only (when only one version of that crate is in the graph)
*   - `"name 1.2.3 (registry+…)"` — name + version + source spec
*     `parseGitUrl`-style detection here treats `source = "git+…"` as the git
*     VCS source, with `#<rev>` as the commit pin. The parser is forgiving —
*     unknown keys ignored, missing fields default to empty. It never throws.
*     Source material (in lock-step order, newest → oldest):
*
*   1. **C++ native parser** in socket-btm/node-smol-builder:
*      additions/source-patched/src/socketsecurity/manifest/parser_cargo.cc
*      Same algorithm — keep the two in lock-step.
*   2. **socket-sdxgen** — algorithm oracle, broader coverage:
*      socket-sdxgen/src/parsers/cargo/index.mts (851 lines)
*   3. **cdxgen** (pinned v11.11.0):
*      https://github.com/CycloneDX/cdxgen/blob/v11.11.0/lib/parsers/rust.js
*      (parseCargoLock)
*   4. **Cargo's own lockfile encoder** — the source of truth for the format we're
*      parsing:
*      https://github.com/rust-lang/cargo/blob/master/src/cargo/core/resolver/encode.rs
*      Lockfile format docs:
*      https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
*      https://doc.rust-lang.org/cargo/reference/resolver.html#lockfile-format
*      Regression guard:
*
*   - `[[patch.unused]]` blocks must NOT materialize as PackageRefs. Only
*     `[[package]]` opens an entry; any other section header (including
*     `[[patch.unused]]`, `[metadata]`, `[patch.crates-io]`, …) closes the
*     current entry to undefined. See the fixture under socket-btm's
*     test/fixtures/sdxgen-bug-regressions/ cargo-patch-unused-no-leak/.
*/
function addToCargoIndex(packageIndex, name, idx) {
	const existing = packageIndex[name];
	if (existing === void 0) packageIndex[name] = idx;
	else if (typeof existing === "number") packageIndex[name] = [existing, idx];
	else require_primordials_array.ArrayPrototypePush(existing, idx);
}
/**
* Strip Cargo's `name version (source)` dependency entry down to just the crate
* name. The version/source are advisory for cycle-breaking and not part of
* `PackageRef.dependencies` (which is a flat list of names, matching the
* npm/yarn/pnpm convention).
*/
function extractCargoDepName(entry) {
	let s = entry;
	if (s.length > 0 && require_primordials_string.StringPrototypeCharCodeAt(s, 0) === 34) s = require_primordials_string.StringPrototypeSlice(s, 1);
	if (s.length > 0 && require_primordials_string.StringPrototypeCharCodeAt(s, s.length - 1) === 34) s = require_primordials_string.StringPrototypeSlice(s, 0, -1);
	const spaceIdx = require_primordials_string.StringPrototypeIndexOf(s, " ");
	if (spaceIdx === -1) return s;
	return require_primordials_string.StringPrototypeSlice(s, 0, spaceIdx);
}
function freezeCargoEntry(entry) {
	const git = entry.source !== void 0 ? parseCargoGitSource(entry.source) : void 0;
	return require_primordials_object.ObjectFreeze({
		__proto__: null,
		name: entry.name,
		version: entry.version,
		resolved: entry.source,
		integrity: entry.checksum,
		ecosystem: "cargo",
		depType: "prod",
		isDev: false,
		isOptional: false,
		isPeer: false,
		isBundled: false,
		vcsUrl: git?.url,
		vcsCommit: git?.commit,
		dependencies: entry.dependencies
	});
}
function jsParseCargoLock(content) {
	const packages = [];
	const packageIndex = { __proto__: null };
	let lockVersion = "1";
	let currentEntry;
	let pos = 0;
	while (pos < content.length) {
		const eol = require_primordials_string.StringPrototypeIndexOf(content, "\n", pos);
		const end = eol === -1 ? content.length : eol;
		const line = require_primordials_string.StringPrototypeSlice(content, pos, end);
		pos = end + 1;
		const trimmed = require_primordials_string.StringPrototypeTrim(line);
		if (trimmed.length === 0 || trimmed[0] === "#") continue;
		if (trimmed[0] === "[") {
			if (currentEntry && currentEntry.name) {
				require_primordials_array.ArrayPrototypePush(packages, freezeCargoEntry(currentEntry));
				addToCargoIndex(packageIndex, currentEntry.name, packages.length - 1);
			}
			if (trimmed === "[[package]]") currentEntry = newCargoEntry();
			else currentEntry = void 0;
			continue;
		}
		if (currentEntry) {
			if (currentEntry.inDependencies) {
				if (require_primordials_string.StringPrototypeIndexOf(trimmed, "]") !== -1) {
					currentEntry.inDependencies = false;
					continue;
				}
				const cleaned = extractCargoDepName(trimmed[trimmed.length - 1] === "," ? require_primordials_string.StringPrototypeSlice(trimmed, 0, -1) : trimmed);
				if (cleaned.length > 0) require_primordials_array.ArrayPrototypePush(currentEntry.dependencies, cleaned);
				continue;
			}
			if (require_primordials_string.StringPrototypeIndexOf(trimmed, "name") === 0) currentEntry.name = stripTomlString(valueAfterEquals(trimmed));
			else if (require_primordials_string.StringPrototypeIndexOf(trimmed, "version") === 0) currentEntry.version = stripTomlString(valueAfterEquals(trimmed));
			else if (require_primordials_string.StringPrototypeIndexOf(trimmed, "source") === 0) currentEntry.source = stripTomlString(valueAfterEquals(trimmed));
			else if (require_primordials_string.StringPrototypeIndexOf(trimmed, "checksum") === 0) currentEntry.checksum = stripTomlString(valueAfterEquals(trimmed));
			else if (require_primordials_string.StringPrototypeIndexOf(trimmed, "dependencies") === 0) {
				const value = valueAfterEquals(trimmed);
				if (require_primordials_string.StringPrototypeIndexOf(value, "[") !== -1 && require_primordials_string.StringPrototypeIndexOf(value, "]") !== -1) {
					const raw = parseInlineArray(value);
					for (let i = 0, { length } = raw; i < length; i++) require_primordials_array.ArrayPrototypePush(currentEntry.dependencies, extractCargoDepName(raw[i]));
				} else currentEntry.inDependencies = true;
			}
		} else if (require_primordials_string.StringPrototypeIndexOf(trimmed, "version") === 0) lockVersion = stripTomlString(valueAfterEquals(trimmed));
	}
	if (currentEntry && currentEntry.name) {
		require_primordials_array.ArrayPrototypePush(packages, freezeCargoEntry(currentEntry));
		addToCargoIndex(packageIndex, currentEntry.name, packages.length - 1);
	}
	return require_primordials_object.ObjectFreeze({
		__proto__: null,
		type: "lockfile",
		lockVersion,
		ecosystem: "cargo",
		packages: require_primordials_object.ObjectFreeze(packages),
		_index: packageIndex
	});
}
function newCargoEntry() {
	return {
		name: "",
		version: "",
		source: void 0,
		checksum: void 0,
		dependencies: [],
		inDependencies: false
	};
}
function parseCargoGitSource(source) {
	if (require_primordials_string.StringPrototypeIndexOf(source, "git+") !== 0) return;
	const hashIdx = require_primordials_string.StringPrototypeIndexOf(source, "#");
	if (hashIdx === -1) return {
		url: source,
		commit: void 0
	};
	return {
		url: require_primordials_string.StringPrototypeSlice(source, 0, hashIdx),
		commit: require_primordials_string.StringPrototypeSlice(source, hashIdx + 1)
	};
}
/**
* Parse a TOML array of strings on a single line: `dependencies = [ "foo 1.0",
* "bar 2.0" ]`. Returns the strings as raw entries (each callsite runs
* `extractCargoDepName`).
*/
function parseInlineArray(value) {
	const start = require_primordials_string.StringPrototypeIndexOf(value, "[");
	const end = require_primordials_string.StringPrototypeIndexOf(value, "]");
	if (start === -1 || end === -1 || end <= start) return [];
	const inner = require_primordials_string.StringPrototypeTrim(require_primordials_string.StringPrototypeSlice(value, start + 1, end));
	if (inner.length === 0) return [];
	const result = [];
	let i = 0;
	while (i < inner.length) {
		while (i < inner.length && (inner[i] === " " || inner[i] === "	" || inner[i] === ",")) i++;
		if (i >= inner.length) break;
		if (require_primordials_string.StringPrototypeCharCodeAt(inner, i) === 34) {
			const closeIdx = require_primordials_string.StringPrototypeIndexOf(inner, "\"", i + 1);
			if (closeIdx === -1) break;
			require_primordials_array.ArrayPrototypePush(result, require_primordials_string.StringPrototypeSlice(inner, i + 1, closeIdx));
			i = closeIdx + 1;
		} else {
			const commaIdx = require_primordials_string.StringPrototypeIndexOf(inner, ",", i);
			const next = commaIdx === -1 ? inner.length : commaIdx;
			require_primordials_array.ArrayPrototypePush(result, require_primordials_string.StringPrototypeTrim(require_primordials_string.StringPrototypeSlice(inner, i, next)));
			i = next;
		}
	}
	return result;
}
/**
* Strip outer double-quotes from a TOML string value.
*/
function stripTomlString(value) {
	let s = require_primordials_string.StringPrototypeTrim(value);
	if (s.length > 0 && require_primordials_string.StringPrototypeCharCodeAt(s, 0) === 34) s = require_primordials_string.StringPrototypeSlice(s, 1);
	if (s.length > 0 && require_primordials_string.StringPrototypeCharCodeAt(s, s.length - 1) === 34) s = require_primordials_string.StringPrototypeSlice(s, 0, -1);
	return s;
}
/**
* Read the value half of a `key = value` TOML line. Returns the raw value text
* (no quote stripping); callers run `stripTomlString` if they want the inner
* string.
*/
function valueAfterEquals(line) {
	const eq = require_primordials_string.StringPrototypeIndexOf(line, "=");
	if (eq === -1) return "";
	return require_primordials_string.StringPrototypeTrim(require_primordials_string.StringPrototypeSlice(line, eq + 1));
}
const parseCargoLock = jsParseCargoLock;

//#endregion
exports.addToCargoIndex = addToCargoIndex;
exports.extractCargoDepName = extractCargoDepName;
exports.freezeCargoEntry = freezeCargoEntry;
exports.jsParseCargoLock = jsParseCargoLock;
exports.newCargoEntry = newCargoEntry;
exports.parseCargoGitSource = parseCargoGitSource;
exports.parseCargoLock = parseCargoLock;
exports.parseInlineArray = parseInlineArray;
exports.stripTomlString = stripTomlString;
exports.valueAfterEquals = valueAfterEquals;