/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

const test = require("tape");
const binary = require("thrift/lib/nodejs/lib/thrift/binary");

const cases = {
  "Should read signed byte": function (assert) {
    assert.equal(1, binary.readByte(0x01));
    assert.equal(-1, binary.readByte(0xff));

    assert.equal(127, binary.readByte(0x7f));
    assert.equal(-128, binary.readByte(0x80));
    assert.end();
  },
  "Should write byte": function (assert) {
    //Protocol simply writes to the buffer. Nothing to test.. yet.
    assert.ok(true);
    assert.end();
  },
  "Should read I16": function (assert) {
    assert.equal(0, binary.readI16([0x00, 0x00]));
    assert.equal(1, binary.readI16([0x00, 0x01]));
    assert.equal(-1, binary.readI16([0xff, 0xff]));

    // Min I16
    assert.equal(-32768, binary.readI16([0x80, 0x00]));
    // Max I16
    assert.equal(32767, binary.readI16([0x7f, 0xff]));
    assert.end();
  },

  "Should write I16": function (assert) {
    assert.deepEqual([0x00, 0x00], binary.writeI16([], 0));
    assert.deepEqual([0x00, 0x01], binary.writeI16([], 1));
    assert.deepEqual([0xff, 0xff], binary.writeI16([], -1));

    // Min I16
    assert.deepEqual([0x80, 0x00], binary.writeI16([], -32768));
    // Max I16
    assert.deepEqual([0x7f, 0xff], binary.writeI16([], 32767));
    assert.end();
  },

  "Should read I32": function (assert) {
    assert.equal(0, binary.readI32([0x00, 0x00, 0x00, 0x00]));
    assert.equal(1, binary.readI32([0x00, 0x00, 0x00, 0x01]));
    assert.equal(-1, binary.readI32([0xff, 0xff, 0xff, 0xff]));

    // Min I32
    assert.equal(-2147483648, binary.readI32([0x80, 0x00, 0x00, 0x00]));
    // Max I32
    assert.equal(2147483647, binary.readI32([0x7f, 0xff, 0xff, 0xff]));
    assert.end();
  },

  "Should write I32": function (assert) {
    assert.deepEqual([0x00, 0x00, 0x00, 0x00], binary.writeI32([], 0));
    assert.deepEqual([0x00, 0x00, 0x00, 0x01], binary.writeI32([], 1));
    assert.deepEqual([0xff, 0xff, 0xff, 0xff], binary.writeI32([], -1));

    // Min I32
    assert.deepEqual(
      [0x80, 0x00, 0x00, 0x00],
      binary.writeI32([], -2147483648),
    );
    // Max I32
    assert.deepEqual([0x7f, 0xff, 0xff, 0xff], binary.writeI32([], 2147483647));
    assert.end();
  },

  "Should read doubles": function (assert) {
    assert.equal(
      0,
      binary.readDouble([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
    );
    assert.equal(
      0,
      binary.readDouble([0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
    );
    assert.equal(
      1,
      binary.readDouble([0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
    );
    assert.equal(
      2,
      binary.readDouble([0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
    );
    assert.equal(
      -2,
      binary.readDouble([0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
    );

    assert.equal(
      Math.PI,
      binary.readDouble([0x40, 0x9, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18]),
    );

    assert.equal(
      Infinity,
      binary.readDouble([0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
    );
    assert.equal(
      -Infinity,
      binary.readDouble([0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
    );

    assert.ok(
      isNaN(
        binary.readDouble([0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
      ),
    );

    assert.equal(
      1 / 3,
      binary.readDouble([0x3f, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55]),
    );

    // Min subnormal positive double
    assert.equal(
      4.9406564584124654e-324,
      binary.readDouble([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]),
    );
    // Min normal positive double
    assert.equal(
      2.2250738585072014e-308,
      binary.readDouble([0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
    );
    // Max positive double
    assert.equal(
      1.7976931348623157e308,
      binary.readDouble([0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]),
    );
    assert.end();
  },

  "Should write doubles": function (assert) {
    assert.deepEqual(
      [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
      binary.writeDouble([], 0),
    );
    assert.deepEqual(
      [0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
      binary.writeDouble([], 1),
    );
    assert.deepEqual(
      [0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
      binary.writeDouble([], 2),
    );
    assert.deepEqual(
      [0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
      binary.writeDouble([], -2),
    );

    assert.deepEqual(
      [0x40, 0x9, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18],
      binary.writeDouble([], Math.PI),
    );

    assert.deepEqual(
      [0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
      binary.writeDouble([], Infinity),
    );
    assert.deepEqual(
      [0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
      binary.writeDouble([], -Infinity),
    );

    assert.deepEqual(
      [0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
      binary.writeDouble([], NaN),
    );

    assert.deepEqual(
      [0x3f, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55],
      binary.writeDouble([], 1 / 3),
    );

    // Min subnormal positive double
    assert.deepEqual(
      [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01],
      binary.writeDouble([], 4.9406564584124654e-324),
    );
    // Min normal positive double
    assert.deepEqual(
      [0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
      binary.writeDouble([], 2.2250738585072014e-308),
    );
    // Max positive double
    assert.deepEqual(
      [0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
      binary.writeDouble([], 1.7976931348623157e308),
    );
    assert.end();
  },
};

Object.keys(cases).forEach(function (caseName) {
  test(caseName, cases[caseName]);
});
