export const SizeChunks = ['b', 'kb', 'Mb', 'Gb', 'Tb', 'Pb', 'Eb'];
export class Size {
    bytes = 0;
    chunk;
    static from(size) {
        if (isSize(size)) {
            return size;
        }
        return new Size(size);
    }
    constructor(size) {
        let chunk;
        if (typeof size === 'object') {
            chunk = normalizeChunk(size);
        }
        else if (typeof size === 'string') {
            chunk = parse(size);
        }
        else {
            chunk = normalizeChunk(size);
        }
        this.chunk = chunk;
        this.bytes = chunkToBytes(chunk);
    }
}
export function isSize(fs) {
    return fs.bytes !== undefined && fs.chunk !== undefined;
}
export function chunkToBytes(chunk) {
    let bytes = 0;
    SizeChunks.forEach((u, i) => {
        if (chunk[u]) {
            bytes += chunk[u] * Math.pow(1024, i);
        }
    });
    return bytes;
}
const regexp = /([0-9.]+)\s*([kmgtpe]?[b]?)?/i;
export function parse(str) {
    const matches = regexp.exec(str);
    if (!matches) {
        throw new Error(`Invalid size ${str}`);
    }
    let size = +matches[1];
    let unit = matches[2];
    if (!unit) {
        return normalizeChunk(size);
    }
    unit = unit.toLowerCase();
    const chunk = {};
    let ulw;
    SizeChunks.forEach((u) => {
        ulw = u.toLowerCase();
        if (unit === ulw || unit + 'b' === ulw) {
            chunk[u] = size;
        }
    });
    if (Object.keys(chunk).length === 0) {
        throw new Error(`Invalid size ${str}`);
    }
    return normalizeChunk(chunk);
}
export function normalizeChunk(chunk) {
    if (typeof chunk !== 'object') {
        chunk = {
            b: chunk
        };
    }
    const _chunk = {};
    SizeChunks.forEach((u) => {
        _chunk[u] = chunk[u] || 0;
    });
    return _chunk;
}
