"use strict";
/* Socket Lib - Built with rolldown */
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_runtime = require('../_virtual/_rolldown/runtime.js');
const require_primordials_error = require('../primordials/error.js');
const require_primordials_array = require('../primordials/array.js');
const require_node_fs = require('../node/fs.js');
const require_node_path = require('../node/path.js');
const require_primordials_object = require('../primordials/object.js');
const require_fs_read_json = require('../fs/read-json.js');
const require_objects_predicates = require('../objects/predicates.js');
const require_process_spawn_child = require('../process/spawn/child.js');
let node_process = require("node:process");
node_process = require_runtime.__toESM(node_process);

//#region src/cover/code.ts
/**
* @file Code coverage utilities for parsing v8 coverage data.
*/
/**
* Calculate coverage metric with percentage.
*/
function calculateMetric(data) {
	const percent = data.total === 0 ? "0.00" : (data.covered / data.total * 100).toFixed(2);
	return {
		covered: data.covered,
		percent,
		total: data.total
	};
}
/**
* Get code coverage metrics from v8 coverage-final.json.
*
* @throws {Error} When coverage file doesn't exist and generateIfMissing is
*   false.
* @throws {Error} When coverage data format is invalid.
*/
async function getCodeCoverage(options) {
	const { coveragePath, generateIfMissing } = {
		__proto__: null,
		coveragePath: (/* @__PURE__ */ require_node_path.getNodePath()).join(node_process.default.cwd(), "coverage/coverage-final.json"),
		generateIfMissing: false,
		...options
	};
	if (!coveragePath) throw new require_primordials_error.ErrorCtor("Coverage path is required");
	if (!(/* @__PURE__ */ require_node_fs.getNodeFs()).existsSync(coveragePath)) if (generateIfMissing) await require_process_spawn_child.spawn("vitest", ["run", "--coverage"], {
		cwd: node_process.default.cwd(),
		stdio: "inherit"
	});
	else throw new require_primordials_error.ErrorCtor(`Coverage file not found at "${coveragePath}". Run tests with coverage first.`);
	const coverageData = await /* @__PURE__ */ require_fs_read_json.readJson(coveragePath);
	if (!/* @__PURE__ */ require_objects_predicates.isPlainObject(coverageData)) throw new require_primordials_error.ErrorCtor(`Invalid coverage data format in "${coveragePath}"`);
	const totals = {
		__proto__: null,
		branches: {
			__proto__: null,
			covered: 0,
			total: 0
		},
		functions: {
			__proto__: null,
			covered: 0,
			total: 0
		},
		lines: {
			__proto__: null,
			covered: 0,
			total: 0
		},
		statements: {
			__proto__: null,
			covered: 0,
			total: 0
		}
	};
	const v8Data = coverageData;
	for (const fileCoverage of require_primordials_object.ObjectValues(v8Data)) {
		if (!/* @__PURE__ */ require_objects_predicates.isPlainObject(fileCoverage)) continue;
		const fc = fileCoverage;
		if (fc.s && /* @__PURE__ */ require_objects_predicates.isPlainObject(fc.s)) {
			const statementCounts = require_primordials_object.ObjectValues(fc.s);
			for (const count of statementCounts) if (typeof count === "number") {
				totals.statements.total += 1;
				if (count > 0) totals.statements.covered += 1;
			}
		}
		if (fc.b && /* @__PURE__ */ require_objects_predicates.isPlainObject(fc.b)) {
			const branchCounts = require_primordials_object.ObjectValues(fc.b);
			for (const branches of branchCounts) if (require_primordials_array.ArrayIsArray(branches)) {
				for (const count of branches) if (typeof count === "number") {
					totals.branches.total += 1;
					if (count > 0) totals.branches.covered += 1;
				}
			}
		}
		if (fc.f && /* @__PURE__ */ require_objects_predicates.isPlainObject(fc.f)) {
			const functionCounts = require_primordials_object.ObjectValues(fc.f);
			for (const count of functionCounts) if (typeof count === "number") {
				totals.functions.total += 1;
				if (count > 0) totals.functions.covered += 1;
			}
		}
		totals.lines.covered = totals.statements.covered;
		totals.lines.total = totals.statements.total;
	}
	return {
		branches: calculateMetric(totals.branches),
		functions: calculateMetric(totals.functions),
		lines: calculateMetric(totals.lines),
		statements: calculateMetric(totals.statements)
	};
}

//#endregion
exports.calculateMetric = calculateMetric;
exports.getCodeCoverage = getCodeCoverage;