var assert = require('assert');
var sodium = require('../build/Release/sodium');


var expected1 = Buffer.from([
    0x16,0x4b,0x7a,0x7b,0xfc,0xf8,0x19,0xe2,
    0xe3,0x95,0xfb,0xe7,0x3b,0x56,0xe0,0xa3,
    0x87,0xbd,0x64,0x22,0x2e,0x83,0x1f,0xd6,
    0x10,0x27,0x0c,0xd7,0xea,0x25,0x05,0x54
]);

var expected2 = Buffer.from([
    0x7b,0x9d,0x83,0x38,0xeb,0x1e,0x3d,0xdd,
    0xba,0x8a,0x9a,0x35,0x08,0xd0,0x34,0xa1,
    0xec,0xbe,0x75,0x11,0x37,0xfa,0x1b,0xcb,
    0xa0,0xf9,0x2a,0x3e,0x6d,0xfc,0x79,0x80,
    0xb8,0x81,0xa8,0x64,0x5f,0x92,0x67,0x22,
    0x74,0x37,0x96,0x4b,0xf3,0x07,0x0b,0xe2,
    0xb3,0x36,0xb3,0xa3,0x20,0xf8,0x25,0xce,
    0xc9,0x87,0x2d,0xb2,0x50,0x4b,0xf3,0x6d
]);

var expected3 = Buffer.from([
    0x73,0xe0,0x0d,0xcb,0xf4,0xf8,0xa3,0x33,
    0x30,0xac,0x52,0xed,0x2c,0xc9,0xd1,0xb2,
    0xef,0xb1,0x77,0x13,0xd3,0xec,0xe3,0x96,
    0x14,0x9f,0x37,0x65,0x3c,0xfe,0x70,0xe7,
    0x1f,0x2c,0x6f,0x9a,0x62,0xc3,0xc5,0x3a,
    0x31,0x8a,0x9a,0x0b,0x3b,0x78,0x60,0xa4,
    0x31,0x6f,0x72,0x9b,0x8d,0x30,0x0f,0x15,
    0x9b,0x2f,0x60,0x93,0xa8,0x60,0xc1,0xed,
]);

var expected4 = Buffer.from([
    0x62,0x27,0xe4,0xce,0x7c,0x7f,0xe7,0xa4,
    0xba,0x9e,0x2a,0xc3,0x42,0xc3,0x5d,0x24,
    0x03,0x3e,0x38,0x8c,0x9b,0xdc,0x29,0x9b,
    0x4a,0x50,0x50,0xf6,0x71,0x70,0xf4,0x83
]);

var key2 = Buffer.from([
    0x41,0x6e,0x6f,0x74,0x68,0x65,0x72,0x20,
    0x6f,0x6e,0x65,0x20,0x67,0x6f,0x74,0x20,
    0x63,0x61,0x75,0x67,0x68,0x74,0x20,0x74,
    0x6f,0x64,0x61,0x79,0x2c,0x20,0x69,0x74,
    0x27,0x73,0x20,0x61,0x6c,0x6c,0x20,0x6f,
    0x76,0x65,0x72,0x20,0x74,0x68,0x65,0x20,
    0x70,0x61,0x70,0x65,0x72,0x73,0x2e,0x20,
    0x22,0x54,0x65,0x65,0x6e,0x61,0x67,0x65,
    0x72,0x20,0x41,0x72,0x72,0x65,0x73,0x74,
    0x65,0x64,0x20,0x69,0x6e,0x20,0x43,0x6f,
    0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x43,
    0x72,0x69,0x6d,0x65,0x20,0x53,0x63,0x61,
    0x6e,0x64,0x61,0x6c,0x22,0x2c,0x20,0x22,
    0x48,0x61,0x63,0x6b,0x65,0x72,0x20,0x41,
    0x72,0x72,0x65,0x73,0x74,0x65,0x64,0x20,
    0x61,0x66,0x74,0x65,0x72,0x20,0x42,0x61,
    0x6e,0x6b,0x20,0x54,0x61,0x6d,0x70,0x65,
    0x72,0x69,0x6e,0x67,0x22,0x2e,0x2e,0x2e,
    0x20,0x44,0x61,0x6d,0x6e,0x20,0x6b,0x69,
    0x64,0x73,0x2e,0x20,0x54,0x68,0x65,0x79,
    0x27,0x72,0x65,0x20,0x61,0x6c,0x6c,0x20,
    0x61,0x6c,0x69,0x6b,0x65,0x2e,0x00
]);

var tKey = Buffer.from("Jefe");
var key = Buffer.alloc(32).fill(0);
tKey.copy(key);

var c = Buffer.from("what do ya want for nothing?");
var firstPart = c.slice(0,1);
var secondPart = c.slice(0, c.length - 1);

describe("libsodium_auth", function () {
    it('crypto_auth', function() {
        var result1 = sodium.crypto_auth(c, key);
        assert(result1.equals(expected1));
    });

    it('crypto_auth_hmacsha512 init, update, final', function() {
        var state = sodium.crypto_auth_hmacsha512_init(key);        
        sodium.crypto_auth_hmacsha512_update(state, firstPart);
        sodium.crypto_auth_hmacsha512_update(state, secondPart);
        var result2 = sodium.crypto_auth_hmacsha512_final(state);
        
        assert(result2.equals(expected2));

        var state2 = sodium.crypto_auth_hmacsha512_init(key2);   
        sodium.crypto_auth_hmacsha512_update(state2, firstPart);
        sodium.crypto_auth_hmacsha512_update(state2, secondPart);
        var result3 = sodium.crypto_auth_hmacsha512_final(state2);
        
        assert(result3.equals(expected3));
    });

    it('crypto_auth_hmacsha256 init, update, final', function() {
        var state3 = sodium.crypto_auth_hmacsha256_init(key2);
        sodium.crypto_auth_hmacsha256_update(state3, null);
        sodium.crypto_auth_hmacsha256_update(state3, firstPart);
        sodium.crypto_auth_hmacsha256_update(state3, secondPart);
        var result4 = sodium.crypto_auth_hmacsha256_final(state3);
        assert(result4.equals(expected4));
    });

    it('check constants' , function() {
        assert(sodium.crypto_auth_BYTES > 0);
        assert(sodium.crypto_auth_KEYBYTES > 0);
        assert.equal(sodium.crypto_auth_PRIMITIVE, "hmacsha512256");

        assert(sodium.crypto_auth_hmacsha256_BYTES > 0);
        assert(sodium.crypto_auth_hmacsha256_KEYBYTES > 0);
        assert(sodium.crypto_auth_hmacsha512_BYTES > 0);
        assert(sodium.crypto_auth_hmacsha512_KEYBYTES > 0);

        assert(sodium.crypto_auth_hmacsha512256_BYTES == sodium.crypto_auth_BYTES);
        assert(sodium.crypto_auth_hmacsha512256_KEYBYTES == sodium.crypto_auth_KEYBYTES);
        assert(sodium.crypto_auth_hmacsha512256_statebytes() >=
            sodium.crypto_auth_hmacsha512256_KEYBYTES);
    })
});

