import { lib, algo, enc, HmacSHA256, PBKDF2 } from 'crypto-js';
import { hexStringToBuffer } from '@iotize/common/byte-converter';
import { KaitaiStreamWriter } from '@iotize/common/byte-stream';
import { ShaHasher } from '@iotize/common/crypto';

class CryptoHelper {
    static sanitizeInput(input) {
        if (input instanceof Uint8Array) {
            return CryptoHelper.byteArrayToWordArray(input);
        }
        else {
            return input;
        }
    }
    static byteArrayToWordArray(ba) {
        const wa = [];
        for (let i = 0; i < ba.length; i++) {
            wa[(i / 4) | 0] |= ba[i] << (24 - 8 * i);
        }
        const result = lib.WordArray.create(wa);
        result.sigBytes = ba.length;
        return result;
    }
    static getAlgoImpl(type) {
        switch (type) {
            case 'sha1':
                return algo.SHA1;
            case 'sha256':
                return algo.SHA256;
            default:
                throw new Error('Unknown algo type: ' + type);
        }
    }
    static wordToByteArray(word, length) {
        const ba = [];
        if (length > 0)
            ba.push(word >>> 24);
        if (length > 1)
            ba.push((word >>> 16) & 0xff);
        if (length > 2)
            ba.push((word >>> 8) & 0xff);
        if (length > 3)
            ba.push(word & 0xff);
        return Uint8Array.from(ba);
    }
    static libWordArrayToByteArray(libWordArray, length) {
        if (!length) {
            length = libWordArray.sigBytes;
        }
        const wordArray = libWordArray.words;
        const result = [];
        let i = 0;
        while (length > 0) {
            const bytes = CryptoHelper.wordToByteArray(wordArray[i], Math.min(4, length));
            length -= bytes.length;
            result.push(bytes);
            i++;
        }
        return KaitaiStreamWriter.mergeArrays(...result);
    }
    static wordArrayToByteArray(input) {
        return hexStringToBuffer(input.toString(enc.Hex));
    }
}

function hmacSHA256(data, key) {
    const wordArray = CryptoHelper.sanitizeInput(data);
    const keyArray = CryptoHelper.sanitizeInput(key);
    const result = HmacSHA256(wordArray, keyArray);
    return CryptoHelper.wordArrayToByteArray(result);
}

/**
 * PBKDF2 function (pssword-based key derivation function)
 * @param input
 * @param salt
 * @iterations
 * @param keySize number of 32 bit words
 */
function pbkdf2(input, salt, iterations, keySize) {
    const wordInput = CryptoHelper.sanitizeInput(input);
    const wordSalt = CryptoHelper.sanitizeInput(salt);
    const options = {
        iterations,
        keySize,
        hasher: algo.SHA256,
    };
    if (options.keySize === undefined) {
        delete options.keySize;
    }
    const hash = PBKDF2(wordInput, wordSalt, options);
    return CryptoHelper.wordArrayToByteArray(hash);
}

const ALGO_TYPE = 'sha1';
const ITERATION_NUMBER = 4096;
const KEY_SIZE = 128;
const DEFAULT_SALT = 'n0 salt in 1oTi2e'; // TODO read from iotize ...
const passwordHasher = new ShaHasher({
    type: ALGO_TYPE,
    iterations: ITERATION_NUMBER,
    salt: DEFAULT_SALT,
    keySize: KEY_SIZE,
});

/**
 * Generated bundle index. Do not edit.
 */

export { hmacSHA256, passwordHasher, pbkdf2 };
//# sourceMappingURL=iotize-tap-crypto.js.map
