"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_buffer = require('../primordials/buffer.js');
const require_primordials_error = require('../primordials/error.js');
const require_primordials_string = require('../primordials/string.js');
const require_primordials_map_set = require('../primordials/map-set.js');
const require_fs_safe = require('../fs/safe.js');
const require_compression__internal = require('./_internal.js');
let node_fs = require("node:fs");
let node_path = require("node:path");
node_path = require_runtime.__toESM(node_path);
let node_util = require("node:util");
let node_stream_promises = require("node:stream/promises");
let node_zlib = require("node:zlib");

//#region src/compression/brotli.ts
const brotliCompressAsync = (0, node_util.promisify)(node_zlib.brotliCompress);
const brotliDecompressAsync = (0, node_util.promisify)(node_zlib.brotliDecompress);
/**
* Translate `CompressOptions` into the `BrotliOptions` zlib expects. Defaults
* `quality` to 11 (max) when not provided, and forwards a positive `size` hint.
* Exposed for callers building their own zlib pipelines and for unit-test
* coverage.
*/
function resolveBrotliOptions(options) {
	const level = options?.level ?? 11;
	const params = { [node_zlib.constants.BROTLI_PARAM_QUALITY]: level };
	if (options?.size !== void 0 && options.size > 0) params[node_zlib.constants.BROTLI_PARAM_SIZE_HINT] = options.size;
	return { params };
}
/**
* Compress a string or Buffer with brotli. Strings are encoded as UTF-8 before
* compression — pass an explicit Buffer if you have non-UTF-8 input.
*/
async function compressBrotli(input, options) {
	const buf = typeof input === "string" ? require_primordials_buffer.BufferFrom(input, "utf8") : input;
	const opts = resolveBrotliOptions(options);
	if (opts.params[node_zlib.constants.BROTLI_PARAM_SIZE_HINT] === void 0) opts.params[node_zlib.constants.BROTLI_PARAM_SIZE_HINT] = buf.byteLength;
	return await brotliCompressAsync(buf, opts);
}
/**
* Decompress a brotli-compressed Buffer.
*/
async function decompressBrotli(input) {
	return await brotliDecompressAsync(input);
}
async function compressBrotliFile(srcPath, destOrOptions, maybeOptions) {
	const { destPath, options, inPlace } = require_compression__internal.resolveFileArgs("compressBrotliFile", srcPath, destOrOptions, maybeOptions, (p) => `${p}.br`);
	await (0, node_stream_promises.pipeline)((0, node_fs.createReadStream)(srcPath), (0, node_zlib.createBrotliCompress)(resolveBrotliOptions(options)), (0, node_fs.createWriteStream)(destPath));
	if (inPlace) await require_fs_safe.safeDelete(srcPath);
	return destPath;
}
async function decompressBrotliFile(srcPath, destOrOptions) {
	const { destPath, inPlace } = require_compression__internal.resolveFileArgs("decompressBrotliFile", srcPath, destOrOptions, void 0, (p) => {
		if (!hasBrotliExt(p)) throw new require_primordials_error.ErrorCtor(`decompressBrotliFile: ${p} has no .br/.brotli extension; can't infer destination`);
		return require_compression__internal.stripExt(p, BROTLI_EXTS);
	});
	await (0, node_stream_promises.pipeline)((0, node_fs.createReadStream)(srcPath), (0, node_zlib.createBrotliDecompress)(), (0, node_fs.createWriteStream)(destPath));
	if (inPlace) await require_fs_safe.safeDelete(srcPath);
	return destPath;
}
/**
* Create a brotli compress transform stream. Compose into your own pipeline.
* The `pipeline` from `node:stream/promises` is the safe way to wire it up — it
* handles error propagation across all stages.
*/
function createBrotliCompressor(options) {
	return (0, node_zlib.createBrotliCompress)(resolveBrotliOptions(options));
}
/**
* Create a brotli decompress transform stream.
*/
function createBrotliDecompressor() {
	return (0, node_zlib.createBrotliDecompress)();
}
const BROTLI_MIN_LEN = 4;
/**
* Cheap pre-flight check: does the buffer look like it could be brotli? Returns
* false for inputs too short to be valid. Brotli has no fixed magic bytes, so
* this is intentionally permissive — the authoritative test is
* `decompressBrotli(buf)` succeeding. Use for UI hints, not correctness.
*/
function isBrotliCompressed(input) {
	return require_primordials_buffer.BufferIsBuffer(input) && input.byteLength >= BROTLI_MIN_LEN;
}
const BROTLI_EXTS = new require_primordials_map_set.SetCtor([".br", ".brotli"]);
/**
* Extension check for brotli paths — matches `.br` / `.brotli`
* (case-insensitive). Naming follows node:path's `extname`.
*/
function hasBrotliExt(filePath) {
	return BROTLI_EXTS.has(require_primordials_string.StringPrototypeToLowerCase(node_path.default.extname(filePath)));
}

//#endregion
exports.BROTLI_EXTS = BROTLI_EXTS;
exports.compressBrotli = compressBrotli;
exports.compressBrotliFile = compressBrotliFile;
exports.createBrotliCompressor = createBrotliCompressor;
exports.createBrotliDecompressor = createBrotliDecompressor;
exports.decompressBrotli = decompressBrotli;
exports.decompressBrotliFile = decompressBrotliFile;
exports.hasBrotliExt = hasBrotliExt;
exports.isBrotliCompressed = isBrotliCompressed;
exports.resolveBrotliOptions = resolveBrotliOptions;