var test = require('tape');
var Buffer = require('buffer').Buffer;

var crypto = require('../');

var algorithms = ['sha1', 'sha256', 'md5'];
var encodings = ['binary', 'hex', 'base64'];


// We can't compare against node's crypto library directly because when
// using testling we only have another version of crypto-browserify to
// check against. So we'll use a cached version of the expected values
// generated by node crypto.
var EXPECTED = {};

EXPECTED['sha1-hash-binary'] = atob('qvTGHdzF6KLavt4PO0gs2a6pQ00=');
EXPECTED['sha1-hash-hex'] = 'aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d';
EXPECTED['sha1-hash-base64'] = 'qvTGHdzF6KLavt4PO0gs2a6pQ00=';

EXPECTED['sha256-hash-binary'] = atob('LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=');
EXPECTED['sha256-hash-hex'] = '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824';
EXPECTED['sha256-hash-base64'] = 'LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=';

EXPECTED['md5-hash-binary'] = atob('XUFAKrxLKna5cZ2REBfFkg==');
EXPECTED['md5-hash-hex'] = '5d41402abc4b2a76b9719d911017c592';
EXPECTED['md5-hash-base64'] = 'XUFAKrxLKna5cZ2REBfFkg==';

EXPECTED['sha1-hmac-binary'] = atob('URIFXAX5RPhXVe/FzYlw4ZTp9Fs=');
EXPECTED['sha1-hmac-hex'] = '5112055c05f944f85755efc5cd8970e194e9f45b';
EXPECTED['sha1-hmac-base64'] = 'URIFXAX5RPhXVe/FzYlw4ZTp9Fs=';

EXPECTED['sha256-hmac-binary'] = atob('iKqz7ejTrflNJquQ07r9SiCDBww7zOnAFO4EpEOEfAs=');
EXPECTED['sha256-hmac-hex'] = '88aab3ede8d3adf94d26ab90d3bafd4a2083070c3bcce9c014ee04a443847c0b';
EXPECTED['sha256-hmac-base64'] = 'iKqz7ejTrflNJquQ07r9SiCDBww7zOnAFO4EpEOEfAs=';

EXPECTED['md5-hmac-binary'] = atob('ut5jhjxh7QsxZYBuzWrO/A==');
EXPECTED['md5-hmac-hex'] = 'bade63863c61ed0b3165806ecd6acefc';
EXPECTED['md5-hmac-base64'] = 'ut5jhjxh7QsxZYBuzWrO/A==';

EXPECTED['md5-with-binary'] = '27549c8ff29ca52f7957f89c328dbb6d';
EXPECTED['sha1-with-binary'] = '4fa10dda29053b237b5d9703151c852c61e6d8d7';
EXPECTED['sha256-with-binary'] = '424ff84246aabc1560a2881b9664108dfe26784c762d930c4ff396c085f4183b';

EXPECTED['md5-empty-string'] = 'd41d8cd98f00b204e9800998ecf8427e';
EXPECTED['sha1-empty-string'] = 'da39a3ee5e6b4b0d3255bfef95601890afd80709';
EXPECTED['sha256-empty-string'] = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';


algorithms.forEach(function (algorithm) {
    encodings.forEach(function (encoding) {
        test(algorithm + ' hash using ' + encoding, function (t) {
            t.plan(1);
            var actual = crypto.createHash(algorithm).update('hello', 'utf-8').digest(encoding);
            var expected = EXPECTED[algorithm + '-hash-' + encoding];
            t.equal(actual, expected);
            t.end();
        });

        test(algorithm + ' hmac using ' + encoding, function (t) {
            t.plan(1);
            var actual = crypto.createHmac(algorithm, 'secret').update('hello', 'utf-8').digest(encoding);
            var expected = EXPECTED[algorithm + '-hmac-' + encoding];
            t.equal(actual, expected);
            t.end();
        });
    });

    test(algorithm + ' with empty string', function (t) {
        t.plan(1);
        var actual = crypto.createHash(algorithm).update('', 'utf-8').digest('hex');
        var expected = EXPECTED[algorithm + '-empty-string'];
        t.equal(actual, expected);
        t.end();
    });

    test(algorithm + ' with raw binary', function (t) {
        t.plan(1);
        var seed = 'hello';
        for (var i = 0; i < 1000; i++) {
            seed = crypto.createHash(algorithm).update(seed).digest('binary');
        }
        var actual = crypto.createHash(algorithm).update(seed).digest('hex');
        var expected = EXPECTED[algorithm + '-with-binary'];
        t.equal(actual, expected);
        t.end();
    });
});


test('randomBytes', function (t) {
    t.plan(5);
    t.equal(crypto.randomBytes(10).length, 10);
    t.ok(crypto.randomBytes(10) instanceof Buffer);
    crypto.randomBytes(10, function(ex, bytes) {
        t.error(ex);
        t.equal(bytes.length, 10);
        t.ok(bytes instanceof Buffer);
        t.end();
  });
});
