// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

/**
 * @fileoverview Test cases for jspb's helper functions.
 *
 * Test suite is written using Jasmine -- see http://jasmine.github.io/
 *
 * @author aappleby@google.com (Austin Appleby)
 */

goog.require('goog.crypt.base64');
goog.require('goog.testing.asserts');
goog.require('jspb.BinaryConstants');
goog.require('jspb.BinaryWriter');
goog.require('jspb.utils');


/**
 * @param {number} x
 * @return {number}
 */
function truncate(x) {
  var temp = new Float32Array(1);
  temp[0] = x;
  return temp[0];
}


/**
 * Converts an 64-bit integer in split representation to a 64-bit hash string
 * (8 bits encoded per character).
 * @param {number} bitsLow The low 32 bits of the split 64-bit integer.
 * @param {number} bitsHigh The high 32 bits of the split 64-bit integer.
 * @return {string} The encoded hash string, 8 bits per character.
 */
function toHashString(bitsLow, bitsHigh) {
  return String.fromCharCode((bitsLow >>> 0) & 0xFF,
                             (bitsLow >>> 8) & 0xFF,
                             (bitsLow >>> 16) & 0xFF,
                             (bitsLow >>> 24) & 0xFF,
                             (bitsHigh >>> 0) & 0xFF,
                             (bitsHigh >>> 8) & 0xFF,
                             (bitsHigh >>> 16) & 0xFF,
                             (bitsHigh >>> 24) & 0xFF);
}


describe('binaryUtilsTest', function() {
  /**
   * Tests lossless binary-to-decimal conversion.
   */
  it('testDecimalConversion', function() {
    // Check some magic numbers.
    var result =
        jspb.utils.joinUnsignedDecimalString(0x89e80001, 0x8ac72304);
    assertEquals('10000000000000000001', result);

    result = jspb.utils.joinUnsignedDecimalString(0xacd05f15, 0x1b69b4b);
    assertEquals('123456789123456789', result);

    result = jspb.utils.joinUnsignedDecimalString(0xeb1f0ad2, 0xab54a98c);
    assertEquals('12345678901234567890', result);

    result = jspb.utils.joinUnsignedDecimalString(0xe3b70cb1, 0x891087b8);
    assertEquals('9876543210987654321', result);

    // Check limits.
    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00000000);
    assertEquals('0', result);

    result = jspb.utils.joinUnsignedDecimalString(0xFFFFFFFF, 0xFFFFFFFF);
    assertEquals('18446744073709551615', result);

    // Check each bit of the low dword.
    for (var i = 0; i < 32; i++) {
      var low = (1 << i) >>> 0;
      result = jspb.utils.joinUnsignedDecimalString(low, 0);
      assertEquals('' + Math.pow(2, i), result);
    }

    // Check the first 20 bits of the high dword.
    for (var i = 0; i < 20; i++) {
      var high = (1 << i) >>> 0;
      result = jspb.utils.joinUnsignedDecimalString(0, high);
      assertEquals('' + Math.pow(2, 32 + i), result);
    }

    // V8's internal double-to-string conversion is inaccurate for values above
    // 2^52, even if they're representable integers - check the rest of the bits
    // manually against the correct string representations of 2^N.

    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00100000);
    assertEquals('4503599627370496', result);

    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00200000);
    assertEquals('9007199254740992', result);

    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00400000);
    assertEquals('18014398509481984', result);

    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00800000);
    assertEquals('36028797018963968', result);

    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x01000000);
    assertEquals('72057594037927936', result);

    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x02000000);
    assertEquals('144115188075855872', result);

    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x04000000);
    assertEquals('288230376151711744', result);

    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x08000000);
    assertEquals('576460752303423488', result);

    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x10000000);
    assertEquals('1152921504606846976', result);

    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x20000000);
    assertEquals('2305843009213693952', result);

    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x40000000);
    assertEquals('4611686018427387904', result);

    result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x80000000);
    assertEquals('9223372036854775808', result);
  });


  /**
   * Going from hash strings to decimal strings should also be lossless.
   */
  it('testHashToDecimalConversion', function() {
    var result;
    var convert = jspb.utils.hash64ToDecimalString;

    result = convert(toHashString(0x00000000, 0x00000000), false);
    assertEquals('0', result);

    result = convert(toHashString(0x00000000, 0x00000000), true);
    assertEquals('0', result);

    result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), false);
    assertEquals('18446744073709551615', result);

    result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), true);
    assertEquals('-1', result);

    result = convert(toHashString(0x00000000, 0x80000000), false);
    assertEquals('9223372036854775808', result);

    result = convert(toHashString(0x00000000, 0x80000000), true);
    assertEquals('-9223372036854775808', result);

    result = convert(toHashString(0xacd05f15, 0x01b69b4b), false);
    assertEquals('123456789123456789', result);

    result = convert(toHashString(~0xacd05f15 + 1, ~0x01b69b4b), true);
    assertEquals('-123456789123456789', result);

    // And converting arrays of hashes should work the same way.
    result = jspb.utils.hash64ArrayToDecimalStrings([
      toHashString(0xFFFFFFFF, 0xFFFFFFFF),
      toHashString(0x00000000, 0x80000000),
      toHashString(0xacd05f15, 0x01b69b4b)], false);
    assertEquals(3, result.length);
    assertEquals('18446744073709551615', result[0]);
    assertEquals('9223372036854775808', result[1]);
    assertEquals('123456789123456789', result[2]);
  });


  /**
   * Going from hash strings to hex strings should be lossless.
   */
  it('testHashToHexConversion', function() {
    var result;
    var convert = jspb.utils.hash64ToHexString;

    result = convert(toHashString(0x00000000, 0x00000000));
    assertEquals('0x0000000000000000', result);

    result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF));
    assertEquals('0xffffffffffffffff', result);

    result = convert(toHashString(0x12345678, 0x9ABCDEF0));
    assertEquals('0x9abcdef012345678', result);
  });


  /**
   * Going from hex strings to hash strings should be lossless.
   */
  it('testHexToHashConversion', function() {
    var result;
    var convert = jspb.utils.hexStringToHash64;

    result = convert('0x0000000000000000');
    assertEquals(String.fromCharCode.apply(null,
        [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), result);

    result = convert('0xffffffffffffffff');
    assertEquals(String.fromCharCode.apply(null,
        [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result);

    // Hex string is big-endian, hash string is little-endian.
    result = convert('0x123456789ABCDEF0');
    assertEquals(String.fromCharCode.apply(null,
        [0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]), result);

    // Capitalization should not matter.
    result = convert('0x0000abcdefABCDEF');
    assertEquals(String.fromCharCode.apply(null,
        [0xEF, 0xCD, 0xAB, 0xEF, 0xCD, 0xAB, 0x00, 0x00]), result);
  });


  /**
   * Going from numbers to hash strings should be lossless for up to 53 bits of
   * precision.
   */
  it('testNumberToHashConversion', function() {
    var result;
    var convert = jspb.utils.numberToHash64;

    result = convert(0x0000000000000);
    assertEquals('0x0000000000000000', jspb.utils.hash64ToHexString(result));

    result = convert(0xFFFFFFFFFFFFF);
    assertEquals('0x000fffffffffffff', jspb.utils.hash64ToHexString(result));

    result = convert(0x123456789ABCD);
    assertEquals('0x000123456789abcd', jspb.utils.hash64ToHexString(result));

    result = convert(0xDCBA987654321);
    assertEquals('0x000dcba987654321', jspb.utils.hash64ToHexString(result));

    // 53 bits of precision should not be truncated.
    result = convert(0x10000000000001);
    assertEquals('0x0010000000000001', jspb.utils.hash64ToHexString(result));

    // 54 bits of precision should be truncated.
    result = convert(0x20000000000001);
    assertNotEquals(
        '0x0020000000000001', jspb.utils.hash64ToHexString(result));
  });


  /**
   * Sanity check the behavior of Javascript's strings when doing funny things
   * with unicode characters.
   */
  it('sanityCheckUnicodeStrings', function() {
    var strings = new Array(65536);

    // All possible unsigned 16-bit values should be storable in a string, they
    // shouldn't do weird things with the length of the string, and they should
    // come back out of the string unchanged.
    for (var i = 0; i < 65536; i++) {
      strings[i] = 'a' + String.fromCharCode(i) + 'a';
      if (3 != strings[i].length) throw 'fail!';
      if (i != strings[i].charCodeAt(1)) throw 'fail!';
    }

    // Each unicode character should compare equal to itself and not equal to a
    // different unicode character.
    for (var i = 0; i < 65536; i++) {
      if (strings[i] != strings[i]) throw 'fail!';
      if (strings[i] == strings[(i + 1) % 65536]) throw 'fail!';
    }
  });


  /**
   * Tests conversion from 32-bit floating point numbers to split64 numbers.
   */
  it('testFloat32ToSplit64', function() {
    var f32_eps = jspb.BinaryConstants.FLOAT32_EPS;
    var f32_min = jspb.BinaryConstants.FLOAT32_MIN;
    var f32_max = jspb.BinaryConstants.FLOAT32_MAX;

    // NaN.
    jspb.utils.splitFloat32(NaN);
    if (!isNaN(jspb.utils.joinFloat32(jspb.utils.split64Low,
                                         jspb.utils.split64High))) {
      throw 'fail!';
    }

    /**
     * @param {number} x
     * @param {number=} opt_bits
     */
    function test(x, opt_bits) {
      jspb.utils.splitFloat32(x);
      if (goog.isDef(opt_bits)) {
        if (opt_bits != jspb.utils.split64Low) throw 'fail!';
      }
      if (truncate(x) != jspb.utils.joinFloat32(jspb.utils.split64Low,
                                                   jspb.utils.split64High)) {
        throw 'fail!';
      }
    }

    // Positive and negative infinity.
    test(Infinity, 0x7f800000);
    test(-Infinity, 0xff800000);

    // Positive and negative zero.
    test(0, 0x00000000);
    test(-0, 0x80000000);

    // Positive and negative epsilon.
    test(f32_eps, 0x00000001);
    test(-f32_eps, 0x80000001);

    // Positive and negative min.
    test(f32_min, 0x00800000);
    test(-f32_min, 0x80800000);

    // Positive and negative max.
    test(f32_max, 0x7F7FFFFF);
    test(-f32_max, 0xFF7FFFFF);

    // Various positive values.
    var cursor = f32_eps * 10;
    while (cursor != Infinity) {
      test(cursor);
      cursor *= 1.1;
    }

    // Various negative values.
    cursor = -f32_eps * 10;
    while (cursor != -Infinity) {
      test(cursor);
      cursor *= 1.1;
    }
  });


  /**
   * Tests conversion from 64-bit floating point numbers to split64 numbers.
   */
  it('testFloat64ToSplit64', function() {
    var f64_eps = jspb.BinaryConstants.FLOAT64_EPS;
    var f64_min = jspb.BinaryConstants.FLOAT64_MIN;
    var f64_max = jspb.BinaryConstants.FLOAT64_MAX;

    // NaN.
    jspb.utils.splitFloat64(NaN);
    if (!isNaN(jspb.utils.joinFloat64(jspb.utils.split64Low,
                                         jspb.utils.split64High))) {
      throw 'fail!';
    }

    /**
     * @param {number} x
     * @param {number=} opt_highBits
     * @param {number=} opt_lowBits
     */
    function test(x, opt_highBits, opt_lowBits) {
      jspb.utils.splitFloat64(x);
      if (goog.isDef(opt_highBits)) {
        if (opt_highBits != jspb.utils.split64High) throw 'fail!';
      }
      if (goog.isDef(opt_lowBits)) {
        if (opt_lowBits != jspb.utils.split64Low) throw 'fail!';
      }
      if (x != jspb.utils.joinFloat64(jspb.utils.split64Low,
                                         jspb.utils.split64High)) {
        throw 'fail!';
      }
    }

    // Positive and negative infinity.
    test(Infinity, 0x7ff00000, 0x00000000);
    test(-Infinity, 0xfff00000, 0x00000000);

    // Positive and negative zero.
    test(0, 0x00000000, 0x00000000);
    test(-0, 0x80000000, 0x00000000);

    // Positive and negative epsilon.
    test(f64_eps, 0x00000000, 0x00000001);
    test(-f64_eps, 0x80000000, 0x00000001);

    // Positive and negative min.
    test(f64_min, 0x00100000, 0x00000000);
    test(-f64_min, 0x80100000, 0x00000000);

    // Positive and negative max.
    test(f64_max, 0x7FEFFFFF, 0xFFFFFFFF);
    test(-f64_max, 0xFFEFFFFF, 0xFFFFFFFF);

    // Various positive values.
    var cursor = f64_eps * 10;
    while (cursor != Infinity) {
      test(cursor);
      cursor *= 1.1;
    }

    // Various negative values.
    cursor = -f64_eps * 10;
    while (cursor != -Infinity) {
      test(cursor);
      cursor *= 1.1;
    }
  });


  /**
   * Tests counting packed varints.
   */
  it('testCountVarints', function() {
    var writer = new jspb.BinaryWriter();

    var count = 0;
    for (var i = 1; i < 1000000000; i *= 1.1) {
      writer.rawWriteVarint(Math.floor(i));
      count++;
    }

    var buffer = new Uint8Array(writer.getResultBuffer());
    assertEquals(count, jspb.utils.countVarints(buffer, 0, buffer.length));
  });


  /**
   * Tests counting matching varint fields.
   */
  it('testCountVarintFields', function() {
    var writer = new jspb.BinaryWriter();

    var count = 0;
    for (var i = 1; i < 1000000000; i *= 1.1) {
      writer.writeUint64(1, Math.floor(i));
      count++;
    }
    writer.writeString(2, 'terminator');

    var buffer = new Uint8Array(writer.getResultBuffer());
    assertEquals(count,
        jspb.utils.countVarintFields(buffer, 0, buffer.length, 1));

    writer = new jspb.BinaryWriter();

    count = 0;
    for (var i = 1; i < 1000000000; i *= 1.1) {
      writer.writeUint64(123456789, Math.floor(i));
      count++;
    }
    writer.writeString(2, 'terminator');

    buffer = new Uint8Array(writer.getResultBuffer());
    assertEquals(count,
        jspb.utils.countVarintFields(buffer, 0, buffer.length, 123456789));
  });


  /**
   * Tests counting matching fixed32 fields.
   */
  it('testCountFixed32Fields', function() {
    var writer = new jspb.BinaryWriter();

    var count = 0;
    for (var i = 1; i < 1000000000; i *= 1.1) {
      writer.writeFixed32(1, Math.floor(i));
      count++;
    }
    writer.writeString(2, 'terminator');

    var buffer = new Uint8Array(writer.getResultBuffer());
    assertEquals(count,
        jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 1));

    writer = new jspb.BinaryWriter();

    count = 0;
    for (var i = 1; i < 1000000000; i *= 1.1) {
      writer.writeFixed32(123456789, Math.floor(i));
      count++;
    }
    writer.writeString(2, 'terminator');

    buffer = new Uint8Array(writer.getResultBuffer());
    assertEquals(count,
        jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 123456789));
  });


  /**
   * Tests counting matching fixed64 fields.
   */
  it('testCountFixed64Fields', function() {
    var writer = new jspb.BinaryWriter();

    var count = 0;
    for (var i = 1; i < 1000000000; i *= 1.1) {
      writer.writeDouble(1, i);
      count++;
    }
    writer.writeString(2, 'terminator');

    var buffer = new Uint8Array(writer.getResultBuffer());
    assertEquals(count,
        jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 1));

    writer = new jspb.BinaryWriter();

    count = 0;
    for (var i = 1; i < 1000000000; i *= 1.1) {
      writer.writeDouble(123456789, i);
      count++;
    }
    writer.writeString(2, 'terminator');

    buffer = new Uint8Array(writer.getResultBuffer());
    assertEquals(count,
        jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 123456789));
  });


  /**
   * Tests counting matching delimited fields.
   */
  it('testCountDelimitedFields', function() {
    var writer = new jspb.BinaryWriter();

    var count = 0;
    for (var i = 1; i < 1000; i *= 1.1) {
      writer.writeBytes(1, [Math.floor(i)]);
      count++;
    }
    writer.writeString(2, 'terminator');

    var buffer = new Uint8Array(writer.getResultBuffer());
    assertEquals(count,
        jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 1));

    writer = new jspb.BinaryWriter();

    count = 0;
    for (var i = 1; i < 1000; i *= 1.1) {
      writer.writeBytes(123456789, [Math.floor(i)]);
      count++;
    }
    writer.writeString(2, 'terminator');

    buffer = new Uint8Array(writer.getResultBuffer());
    assertEquals(count,
        jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 123456789));
  });


  /**
   * Tests byte format for debug strings.
   */
  it('testDebugBytesToTextFormat', function() {
    assertEquals('""', jspb.utils.debugBytesToTextFormat(null));
    assertEquals('"\\x00\\x10\\xff"',
        jspb.utils.debugBytesToTextFormat([0, 16, 255]));
  });


  /**
   * Tests converting byte blob sources into byte blobs.
   */
  it('testByteSourceToUint8Array', function() {
    var convert = jspb.utils.byteSourceToUint8Array;

    var sourceData = [];
    for (var i = 0; i < 256; i++) {
      sourceData.push(i);
    }

    var sourceBytes = new Uint8Array(sourceData);
    var sourceBuffer = sourceBytes.buffer;
    var sourceBase64 = goog.crypt.base64.encodeByteArray(sourceData);
    var sourceString = String.fromCharCode.apply(null, sourceData);

    function check(result) {
      assertEquals(Uint8Array, result.constructor);
      assertEquals(sourceData.length, result.length);
      for (var i = 0; i < result.length; i++) {
        assertEquals(sourceData[i], result[i]);
      }
    }

    // Converting Uint8Arrays into Uint8Arrays should be a no-op.
    assertEquals(sourceBytes, convert(sourceBytes));

    // Converting Array.<numbers> into Uint8Arrays should work.
    check(convert(sourceData));

    // Converting ArrayBuffers into Uint8Arrays should work.
    check(convert(sourceBuffer));

    // Converting base64-encoded strings into Uint8Arrays should work.
    check(convert(sourceBase64));

    // Converting binary-data strings into Uint8Arrays should work.
    check(convert(sourceString, /* opt_stringIsRawBytes = */ true));
  });
});
