"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_math = require('../primordials/math.js');
const require_primordials_date = require('../primordials/date.js');
const require_errors_message = require('../errors/message.js');
const require_debug_output = require('../debug/output.js');
const require_perf__internal = require('./_internal.js');
const require_perf_enabled = require('./enabled.js');
let node_process = require("node:process");
node_process = require_runtime.__toESM(node_process);

//#region src/perf/timer.ts
/**
* @file Recording-side helpers — `perfTimer` (returns a stop() closure),
*   `measure` / `measureSync` (timed wrappers around an async / sync function),
*   `perfCheckpoint` (zero-duration marker), and `trackMemory` (records
*   heap-used at a label). All push rows into the shared metrics array when
*   `isPerfEnabled()` is true.
*/
/**
* Measure execution time of an async function.
*
* @example
*   import { measure } from '@socketsecurity/lib/perf/timer'
*
*   const { result, duration } = await measure('fetch-packages', async () => {
*     return await fetchPackages()
*   })
*   console.log(`Fetched packages in ${duration}ms`)
*
* @param operation - Name of the operation.
* @param fn - Async function to measure.
* @param metadata - Optional metadata.
*
* @returns Result of the function and duration
*/
async function measure(operation, fn, metadata) {
	const stop = perfTimer(operation, metadata);
	try {
		const result = await fn();
		stop({ success: true });
		return {
			result,
			duration: require_perf__internal.performanceMetrics[require_perf__internal.performanceMetrics.length - 1]?.duration || 0
		};
	} catch (e) {
		stop({
			success: false,
			error: require_errors_message.errorMessage(e)
		});
		throw e;
	}
}
/**
* Measure synchronous function execution time.
*
* @example
*   import { measureSync } from '@socketsecurity/lib/perf/timer'
*
*   const { result, duration } = measureSync('parse-json', () => {
*     return JSON.parse(data)
*   })
*
* @param operation - Name of the operation.
* @param fn - Synchronous function to measure.
* @param metadata - Optional metadata.
*
* @returns Result of the function and duration
*/
function measureSync(operation, fn, metadata) {
	const stop = perfTimer(operation, metadata);
	try {
		const result = fn();
		stop({ success: true });
		return {
			result,
			duration: require_perf__internal.performanceMetrics[require_perf__internal.performanceMetrics.length - 1]?.duration || 0
		};
	} catch (e) {
		stop({
			success: false,
			error: require_errors_message.errorMessage(e)
		});
		throw e;
	}
}
/**
* Mark a checkpoint in performance tracking. Useful for tracking progress
* through complex operations.
*
* @example
*   import { perfCheckpoint } from '@socketsecurity/lib/perf/timer'
*
*   perfCheckpoint('start-scan')
*   // ... do work ...
*   perfCheckpoint('fetch-packages', { count: 50 })
*   // ... do work ...
*   perfCheckpoint('analyze-issues', { issueCount: 10 })
*   perfCheckpoint('end-scan')
*
* @param checkpoint - Name of the checkpoint.
* @param metadata - Optional metadata.
*/
function perfCheckpoint(checkpoint, metadata) {
	if (!require_perf_enabled.isPerfEnabled()) return;
	const metric = {
		operation: `checkpoint:${checkpoint}`,
		duration: 0,
		timestamp: require_primordials_date.DateNow(),
		...metadata ? { metadata } : {}
	};
	require_perf__internal.performanceMetrics.push(metric);
	require_debug_output.debugLog(`[perf] [CHECKPOINT] ${checkpoint}`);
}
/**
* Start a performance timer for an operation. Returns a stop function that
* records the duration.
*
* @example
*   import { perfTimer } from '@socketsecurity/lib/perf/timer'
*
*   const stop = perfTimer('api-call')
*   await fetchData()
*   stop({ endpoint: '/npm/lodash/score' })
*
* @param operation - Name of the operation being timed.
* @param metadata - Optional metadata to attach to the metric.
*
* @returns Stop function that completes the timing
*/
function perfTimer(operation, metadata) {
	if (!require_perf_enabled.isPerfEnabled()) return () => {};
	const start = performance.now();
	require_debug_output.debugLog(`[perf] [START] ${operation}`);
	return (additionalMetadata) => {
		const metric = {
			operation,
			duration: require_primordials_math.MathRound((performance.now() - start) * 100) / 100,
			timestamp: require_primordials_date.DateNow(),
			metadata: {
				...metadata,
				...additionalMetadata
			}
		};
		require_perf__internal.performanceMetrics.push(metric);
		require_debug_output.debugLog(`[perf] [END] ${operation} - ${metric.duration}ms`);
	};
}
/**
* Track memory usage at a specific point. Only available when DEBUG=perf is
* enabled.
*
* @example
*   import { trackMemory } from '@socketsecurity/lib/perf/timer'
*
*   const memBefore = trackMemory('before-operation')
*   await heavyOperation()
*   const memAfter = trackMemory('after-operation')
*   console.log(`Memory increased by ${memAfter - memBefore}MB`)
*
* @param label - Label for this memory snapshot.
*
* @returns Memory usage in MB
*/
function trackMemory(label) {
	if (!require_perf_enabled.isPerfEnabled()) return 0;
	const usage = node_process.default.memoryUsage();
	const heapUsedMB = require_primordials_math.MathRound(usage.heapUsed / 1024 / 1024 * 100) / 100;
	require_debug_output.debugLog(`[perf] [MEMORY] ${label}: ${heapUsedMB}MB heap used`);
	const metric = {
		operation: `checkpoint:memory:${label}`,
		duration: 0,
		timestamp: require_primordials_date.DateNow(),
		metadata: {
			heapUsed: heapUsedMB,
			heapTotal: require_primordials_math.MathRound(usage.heapTotal / 1024 / 1024 * 100) / 100,
			external: require_primordials_math.MathRound(usage.external / 1024 / 1024 * 100) / 100
		}
	};
	require_perf__internal.performanceMetrics.push(metric);
	return heapUsedMB;
}

//#endregion
exports.measure = measure;
exports.measureSync = measureSync;
exports.perfCheckpoint = perfCheckpoint;
exports.perfTimer = perfTimer;
exports.trackMemory = trackMemory;