(function () {
  'use strict';

  var crypto = window.crypto;
  var Unibabel = window.Unibabel;

  function deriveKey(saltHex, passphrase, iter) {
    var keyLenBits = 128;
    var kdfname = "PBKDF2";
    var aesname = "AES-CBC"; // AES-CTR is also popular
    // 100 - probably safe even on a browser running from a raspberry pi using pure js ployfill
    // 10000 - no noticeable speed decrease on my MBP
    // 100000 - you can notice
    // 1000000 - annoyingly long
    var iterations = iter || 100; // something a browser on a raspberry pi or old phone could do
    var hashname = "SHA-256";
    var extractable = true;

    console.log('');
    console.log('passphrase', passphrase);
    console.log('salt (hex)', saltHex);
    //console.log('salt (hex)', Unibabel.bufferToHex(saltBuf));
    console.log('iterations', iterations);
    console.log('keyLen (bytes)', keyLenBits / 8);
    console.log('digest', hashname);

    // First, create a PBKDF2 "key" containing the password
    return crypto.subtle.importKey(
      "raw",
      Unibabel.utf8ToBuffer(passphrase),
      { "name": kdfname },
      false,
      ["deriveKey"]).
    // Derive a key from the password
    then(function (passphraseKey) {
      return crypto.subtle.deriveKey(
        { "name": kdfname
        , "salt": Unibabel.hexToBuffer(saltHex)
        , "iterations": iterations
        , "hash": hashname
        }
      , passphraseKey
        // required to be 128 or 256 bits
      , { "name": aesname, "length": keyLenBits } // Key we want
      , extractable                               // Extractble
      , [ "encrypt", "decrypt" ]                  // For new key
      );
    }).
    // Export it so we can display it
    then(function (aesKey) {
      return crypto.subtle.exportKey("raw", aesKey).then(function (arrbuf) {
        return new Uint8Array(arrbuf);
      });
    }).
    catch(function (err) {
      window.alert("Key derivation failed: " + err.message);
    });
  }

  function test() {
    // Part of the salt is application-specific (same on iOS, Android, and Web)
    var saltHex = '942c2db750b5f57f330226b2b498c6d3';
    var passphrase = 'Pizzas are like children';
    //var passphrase = "I'm a ☢ ☃ who speaks 中国语文!";
    var iter = 1672;

    // NOTE: the salt will be truncated to the length of the hash algo being used
    return deriveKey(saltHex, passphrase, iter).then(function (keyBuf) {
      var hexKey = Unibabel.bufferToHex(keyBuf);
      console.log('[TEST] hexKey');
      console.log(hexKey);
    });
  }

  test();
}());
