function createCrcTable() {
    const table = [];
    for (let n = 0; n < 256; n++) {
        let c = n;
        for (let k = 0; k < 8; k++) {
            c = (c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1);
        }
        table[n] = c;
    }
    return table;
}

async function crc32(buffer) {
    let crc = 0 ^ (-1);
    const bytes = new Uint8Array(buffer);
    for (let i = 0; i < bytes.byteLength; i++) {
        crc = (crc >>> 8) ^ crcTable[(crc ^ bytes[i]) & 0xFF];
    }
    return ((crc ^ (-1)) >>> 0).toString(16).padStart(8, '0');
}

async function sha1(buffer) {
    const hashBuffer = await crypto.subtle.digest('SHA-1', buffer);
    return Array.from(new Uint8Array(hashBuffer))
        .map(b => b.toString(16).padStart(2, '0'))
        .join('');
}

const crcTable = createCrcTable();

export async function calculate( file ){
    return new Promise( ( resolve, reject ) => {
        const freader = new FileReader();

        freader.onload = async e => {
            try {
                const buffer = e.target.result;
                const crc32V = await crc32(buffer);
                const sha1V = await sha1(buffer);

                resolve({
                    filename: file.name,
                    crc32: crc32V,
                    sha1: sha1V
                });
            } catch (error) {
                reject(error);
            }
        }

        freader.onerror = () => {
            reject( new Error(`Could not parse file: ${file.name}`) );
        }
        freader.readAsArrayBuffer(file);
    })
}
