import { Writable, Transform } from 'node:stream';
import util from 'node:util';
import ncrypto from 'node:crypto';
import zlib from 'node:zlib';
import './prototype.js';
import './platform.js';
import { assert, check, decode, defer } from './utils.common.js';
export * from './utils.common.js';
/** `180` 输出字符宽度 */
export const output_width = 180;
export const url_width = 52;
/** - colors?: `true` */
export function set_inspect_options(colors = true) {
    util.inspect.defaultOptions.maxArrayLength = 40;
    util.inspect.defaultOptions.maxStringLength = 10000;
    util.inspect.defaultOptions.breakLength = output_width;
    util.inspect.defaultOptions.colors = colors;
    util.inspect.defaultOptions.compact = false;
    util.inspect.defaultOptions.getters = true;
    util.inspect.defaultOptions.depth = 2;
    util.inspect.defaultOptions.sorted = false;
    util.inspect.defaultOptions.showProxy = true;
    util.inspect.styles.number = 'green';
    util.inspect.styles.string = 'cyan';
    util.inspect.styles.boolean = 'blue';
    util.inspect.styles.date = 'magenta';
    util.inspect.styles.special = 'white';
}
export function typed_array_to_buffer(view) {
    return Buffer.from(view.buffer, view.byteOffset, view.byteLength);
}
export function log_line() {
    console.log('---');
}
export function sha256(data) {
    return ncrypto.hash('sha256', data);
}
export function sha1(data) {
    return ncrypto.hash('sha1', data);
}
export function crc32(data) {
    return zlib.crc32(data).toString(16).padStart(8, '0');
}
export function escape_line_feed(str) {
    return str.replace(/\n/g, '\\n');
}
/** util.inspect(obj)
    - options
        - limit?: `10000`  传 0 时不限制
        - omit?: string[] */
export function inspect(obj, options = {}) {
    if (options.omit) {
        obj = { ...obj };
        for (const key of options.omit)
            delete obj[key];
        // 改变了 obj 的引用，去掉 inspect.custom 防止无限递归 inspect
        delete obj[inspect.custom];
    }
    let text = util.inspect(obj, options);
    const limit = options.limit ?? 10000;
    if (limit && text.length > limit)
        return `${text.slice(0, limit)}……'\u001b[39m\n`;
    else
        return text;
}
inspect.custom = util.inspect.custom;
inspect.defaultOptions = util.inspect.defaultOptions;
/** 根据 enabled 选项返回有 / 无颜色的字符串 (str) */
export function colored(str, color, enabled = inspect.defaultOptions.colors) {
    return enabled ? str[color] : str;
}
// ------------------------------------ stream
/** 消费一个可读流 */
export async function consume_stream(stream, ignore_error = false) {
    try {
        for await (const chunk of stream)
            ;
    }
    catch (error) {
        if (!ignore_error)
            throw error;
    }
}
export async function* stream_to_lines(stream) {
    let buf = '';
    for await (const chunk of stream) {
        let j = 0;
        for (let i = 0; (i = chunk.indexOf('\n', j)) >= 0;) {
            let line = chunk.slice(j, i);
            if (buf) {
                line = buf + line;
                buf = '';
            }
            j = i + 1;
            yield line;
        }
        buf = chunk.slice(j);
    }
}
export class WritableMemoryStream extends Writable {
    chunks = [];
    pbuffer = defer();
    constructor() {
        super({ highWaterMark: 2 ** 30, decodeStrings: false });
    }
    _write(chunk, encoding, callback) {
        this.chunks.push(chunk);
        callback();
    }
    _writev(chunks, callback) {
        for (const { chunk } of chunks)
            this.chunks.push(chunk);
        callback();
    }
    _final(callback) {
        this.pbuffer.resolve(Buffer.concat(this.chunks));
        this.chunks = null;
        callback();
    }
}
/** 用 TextDecoder 通过 .pipe 方法持续的解码 process.stdout 等流，
    主要在 process.ts#start 中使用
    https://nodejs.org/api/stream.html#implementing-a-transform-stream */
export class DecoderStream extends Transform {
    decoder;
    constructor(encoding) {
        super({ encoding: 'utf-8' });
        this.decoder = new TextDecoder(encoding);
    }
    _transform(chunk, encoding, callback) {
        assert(chunk instanceof Uint8Array);
        const str = this.decoder.decode(chunk, { stream: true });
        if (str.length)
            this.push(str, 'utf-8');
        callback();
    }
    _flush(callback) {
        const str = this.decoder.decode();
        if (str.length)
            this.push(str, 'utf-8');
        callback();
    }
}
/** 返回一个 transform 流，来截取可读流的前 nbytes 字节 */
export function slice_stream(nbytes) {
    let remaining = nbytes;
    return new Transform({
        transform(chunk, encoding, callback) {
            if (chunk.length < remaining) {
                remaining -= chunk.length;
                callback(null, chunk);
                return;
            }
            // 最后一块
            check(chunk.length === remaining, '可读流最后一块大小应该不超过 remaining');
            this.push(chunk);
            this.push(null);
            callback();
        }
    });
}
/** 根据 range 生成整数序列 (iterable)
    - range: 取值为逗号分割的多个可用值或值区间 (不能含有空格)，比如：`8321,8322,8300-8310,11000-11999`
    - reverse?: `false` 在 range 内从后往前生成 */
export function* range_to_numbers(range, reverse = false) {
    let parts = range.split(',');
    if (reverse)
        parts.reverse();
    for (const part of parts) {
        const [left, right] = part.split('-').map(n => Number(n));
        if (!right)
            yield left;
        if (reverse)
            for (let i = right; i >= left; i--)
                yield i;
        else
            for (let i = left; i <= right; i++)
                yield i;
    }
}
export function decode_buffer_hex_string(str) {
    return decode(Buffer.from(str.split(' ')
        .map(x => parseInt(x, 16))));
}
//# sourceMappingURL=utils.js.map