/*
 * 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.
 */

import Int64 = require("node-int64");
import JSONInt64 = require('json-int64');
import i64types = require("./gen-nodejs/Int64Test_types");
import test = require("tape");

const cases = {
  "should correctly generate Int64 constants": function(assert) {
    const EXPECTED_SMALL_INT64_AS_NUMBER: number = 42;
    const EXPECTED_SMALL_INT64: Int64 = new Int64(42);
    const EXPECTED_MAX_JS_SAFE_INT64: Int64 = new Int64(Number.MAX_SAFE_INTEGER);
    const EXPECTED_MIN_JS_SAFE_INT64: Int64 = new Int64(Number.MIN_SAFE_INTEGER);
    const EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64: Int64 = new Int64("0020000000000000"); // hex-encoded
    const EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64: Int64 = new Int64("ffe0000000000000"); // hex-encoded 2's complement
    const EXPECTED_MAX_SIGNED_INT64: Int64 = new Int64("7fffffffffffffff"); // hex-encoded
    const EXPECTED_MIN_SIGNED_INT64: Int64 = new Int64("8000000000000000"); // hex-encoded 2's complement
    const EXPECTED_INT64_LIST: Int64[] = [
      EXPECTED_SMALL_INT64,
      EXPECTED_MAX_JS_SAFE_INT64,
      EXPECTED_MIN_JS_SAFE_INT64,
      EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64,
      EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64,
      EXPECTED_MAX_SIGNED_INT64,
      EXPECTED_MIN_SIGNED_INT64
    ];

    assert.ok(EXPECTED_SMALL_INT64.equals(i64types.SMALL_INT64));
    assert.ok(EXPECTED_MAX_JS_SAFE_INT64.equals(i64types.MAX_JS_SAFE_INT64));
    assert.ok(EXPECTED_MIN_JS_SAFE_INT64.equals(i64types.MIN_JS_SAFE_INT64));
    assert.ok(
      EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64.equals(
        i64types.MAX_JS_SAFE_PLUS_ONE_INT64
      )
    );
    assert.ok(
      EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64.equals(
        i64types.MIN_JS_SAFE_MINUS_ONE_INT64
      )
    );
    assert.ok(EXPECTED_MAX_SIGNED_INT64.equals(i64types.MAX_SIGNED_INT64));
    assert.ok(EXPECTED_MIN_SIGNED_INT64.equals(i64types.MIN_SIGNED_INT64));
    assert.equal(
      EXPECTED_SMALL_INT64_AS_NUMBER,
      i64types.SMALL_INT64.toNumber()
    );
    assert.equal(
      Number.MAX_SAFE_INTEGER,
      i64types.MAX_JS_SAFE_INT64.toNumber()
    );
    assert.equal(
      Number.MIN_SAFE_INTEGER,
      i64types.MIN_JS_SAFE_INT64.toNumber()
    );

    for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i) {
      assert.ok(EXPECTED_INT64_LIST[i].equals(i64types.INT64_LIST[i]));
    }

    for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i){
      let int64Object = EXPECTED_INT64_LIST[i];
      assert.ok(i64types.INT64_2_INT64_MAP[JSONInt64.toDecimalString(int64Object)].equals(int64Object));
    }

    assert.end();
  }
};

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