// Run this using JavaScriptTest.sh
import assert from 'assert'
import * as flatbuffers from 'flatbuffers'
import fs from 'fs'

import {Any} from './my-game/example/any.js';
import {Color} from './my-game/example/color.js';
import {Monster, MonsterT} from './my-game/example/monster.js'
import {Stat} from './my-game/example/stat.js'
import {Test, TestT} from './my-game/example/test.js'
import {Vec3} from './my-game/example/vec3.js'

function main() {
  // First, let's test reading a FlatBuffer generated by C++ code:
  // This file was generated from monsterdata_test.json
  var data = new Uint8Array(fs.readFileSync('../monsterdata_test.mon'));

  // Now test it:

  var bb = new flatbuffers.ByteBuffer(data);
  testBuffer(bb);

  // Second, let's create a FlatBuffer from scratch in JavaScript, and test it
  // also. We use an initial size of 1 to exercise the reallocation algorithm,
  // normally a size larger than the typical FlatBuffer you generate would be
  // better for performance.
  var fbb = new flatbuffers.Builder(1);
  createMonster(fbb);
  serializeAndTest(fbb);
  testObjApiPack(fbb);

  // clear the builder, repeat tests
  var clearIterations = 100;
  var startingCapacity = fbb.bb.capacity();
  for (var i = 0; i < clearIterations; i++) {
    fbb.clear();
    createMonster(fbb);
    serializeAndTest(fbb);
    testObjApiPack(fbb);
  }
  // the capacity of our buffer shouldn't increase with the same size payload
  assert.strictEqual(fbb.bb.capacity(), startingCapacity);

  test64bit();
  testUnicode();
  fuzzTest1();
  testNullStrings();
  testSharedStrings();
  testVectorOfStructs();
  testCreateByteVector();

  console.log('FlatBuffers test: completed successfully');
}

function createMonster(fbb) {
  // We set up the same values as monsterdata.json:

  var str = fbb.createString('MyMonster');

  var inv = Monster.createInventoryVector(fbb, [0, 1, 2, 3, 4]);

  var fred = fbb.createString('Fred');
  Monster.startMonster(fbb);
  Monster.addName(fbb, fred);
  var mon2 = Monster.endMonster(fbb);

  Monster.startTest4Vector(fbb, 2);
  Test.createTest(fbb, 10, 20);
  Test.createTest(fbb, 30, 40);
  var test4 = fbb.endVector();

  var testArrayOfString = Monster.createTestarrayofstringVector(
      fbb, [fbb.createString('test1'), fbb.createString('test2')]);

  var testVectorOfLongs =
      Monster.createVectorOfLongsVector(fbb, [1n, 101010100n]);

  Monster.startMonster(fbb);
  Monster.addPos(fbb, Vec3.createVec3(fbb, 1, 2, 3, 3, Color.Green, 5, 6));
  Monster.addHp(fbb, 80);
  Monster.addName(fbb, str);
  Monster.addInventory(fbb, inv);
  Monster.addTestType(fbb, Any.Monster);
  Monster.addTest(fbb, mon2);
  Monster.addTest4(fbb, test4);
  Monster.addTestarrayofstring(fbb, testArrayOfString);
  Monster.addVectorOfLongs(fbb, testVectorOfLongs);
  Monster.addTestbool(fbb, true);
  var mon = Monster.endMonster(fbb);

  Monster.finishMonsterBuffer(fbb, mon);
}

function serializeAndTest(fbb) {
  // Write the result to a file for debugging purposes:
  // Note that the binaries are not necessarily identical, since the JSON
  // parser may serialize in a slightly different order than the above
  // JavaScript code. They are functionally equivalent though.

  fs.writeFileSync(
      'monsterdata_javascript_wire.mon', Buffer.from(fbb.asUint8Array()));

  // Tests mutation first.  This will verify that we did not trample any other
  // part of the byte buffer.
  testMutation(fbb.dataBuffer());

  testBuffer(fbb.dataBuffer());
}

function testMutation(bb) {
  var monster = Monster.getRootAsMonster(bb);

  monster.mutate_hp(120);
  assert.strictEqual(monster.hp(), 120);

  monster.mutate_hp(80);
  assert.strictEqual(monster.hp(), 80);

  var manaRes = monster.mutate_mana(10);
  assert.strictEqual(
      manaRes, false);  // Field was NOT present, because default value.

  // TODO: There is not the availability to mutate structs or vectors.
}

function testObjApiPack(fbb) {
  fbb.clear();
  createMonster(fbb);
  let monster_t = Monster.getRootAsMonster(fbb.dataBuffer()).unpack();
  fbb.clear();
  Monster.finishMonsterBuffer(fbb, monster_t.pack(fbb));
  serializeAndTest(fbb);
}

function testObjApiUnpack(monster) {
  assert.strictEqual(monster.hp, 80);
  assert.strictEqual(monster.mana, 150);  // default

  assert.strictEqual(monster.name, 'MyMonster');

  let pos = monster.pos;
  assert.strictEqual(pos.x, 1);
  assert.strictEqual(pos.y, 2);
  assert.strictEqual(pos.z, 3);
  assert.strictEqual(pos.test1, 3);
  assert.strictEqual(pos.test2, Color.Green);
  let test3 = pos.test3;
  assert.strictEqual(test3.a, 5);
  assert.strictEqual(test3.b, 6);

  assert.strictEqual(monster.testType, Any.Monster);
  let monster2 = monster.test;
  assert.strictEqual(monster2 != null, true);
  assert.strictEqual(monster2 instanceof MonsterT, true);
  assert.strictEqual(monster2.name, 'Fred');

  assert.strictEqual(monster.inventory.length, 5);
  let invsum = 0;
  for (let i = 0; i < monster.inventory.length; i++) {
    invsum += monster.inventory[i];
  }
  assert.strictEqual(invsum, 10);

  let test_0 = monster.test4[0];
  let test_1 = monster.test4[1];
  assert.strictEqual(monster.test4.length, 2);
  assert.strictEqual(test_0.a + test_0.b + test_1.a + test_1.b, 100);

  assert.strictEqual(monster.testarrayofstring.length, 2);
  assert.strictEqual(monster.testarrayofstring[0], 'test1');
  assert.strictEqual(monster.testarrayofstring[1], 'test2');

  assert.strictEqual(monster.testbool, true);
}

function testBuffer(bb) {
  assert.ok(Monster.bufferHasIdentifier(bb));

  var monster = Monster.getRootAsMonster(bb);

  assert.strictEqual(monster.hp(), 80);
  assert.strictEqual(monster.mana(), 150);  // default

  assert.strictEqual(monster.name(), 'MyMonster');

  var pos = monster.pos();
  assert.strictEqual(pos.x(), 1);
  assert.strictEqual(pos.y(), 2);
  assert.strictEqual(pos.z(), 3);
  assert.strictEqual(pos.test1(), 3);
  assert.strictEqual(pos.test2(), Color.Green);
  var t = pos.test3();
  assert.strictEqual(t.a(), 5);
  assert.strictEqual(t.b(), 6);

  assert.strictEqual(monster.testType(), Any.Monster);
  var monster2 = new Monster();
  assert.strictEqual(monster.test(monster2) != null, true);
  assert.strictEqual(monster2.name(), 'Fred');

  assert.strictEqual(monster.inventoryLength(), 5);
  var invsum = 0;
  for (var i = 0; i < monster.inventoryLength(); i++) {
    invsum += monster.inventory(i);
  }
  assert.strictEqual(invsum, 10);

  var invsum2 = 0;
  var invArr = monster.inventoryArray();
  for (var i = 0; i < invArr.length; i++) {
    invsum2 += invArr[i];
  }
  assert.strictEqual(invsum2, 10);

  let longSum = 0n;
  for (let idx = 0; idx < monster.vectorOfLongsLength(); ++idx) {
    longSum += monster.vectorOfLongs(idx);
  }
  assert.strictEqual(longSum, 101010101n);

  var test_0 = monster.test4(0);
  var test_1 = monster.test4(1);
  assert.strictEqual(monster.test4Length(), 2);
  assert.strictEqual(test_0.a() + test_0.b() + test_1.a() + test_1.b(), 100);

  assert.strictEqual(monster.testarrayofstringLength(), 2);
  assert.strictEqual(monster.testarrayofstring(0), 'test1');
  assert.strictEqual(monster.testarrayofstring(1), 'test2');

  assert.strictEqual(monster.testbool(), true);

  let monster_t = monster.unpack();
  testObjApiUnpack(monster_t);

  let monster2_t = new MonsterT();
  monster.unpackTo(monster2_t);
  testObjApiUnpack(monster2_t);
}

function test64bit() {
  var fbb = new flatbuffers.Builder();
  var required = fbb.createString('required');

  Stat.startStat(fbb);
  var stat2 = Stat.endStat(fbb);

  Monster.startMonster(fbb);
  Monster.addName(fbb, required);
  Monster.addTestempty(fbb, stat2);
  var mon2 = Monster.endMonster(fbb);

  Stat.startStat(fbb);
  // 2541551405100253985 = 0x2345678987654321
  Stat.addVal(fbb, 0x2345678987654321n);
  var stat = Stat.endStat(fbb);

  Monster.startMonster(fbb);
  Monster.addName(fbb, required);
  Monster.addEnemy(fbb, mon2);
  Monster.addTestempty(fbb, stat);
  var mon = Monster.endMonster(fbb);

  Monster.finishMonsterBuffer(fbb, mon);
  var bytes = fbb.asUint8Array();

  ////////////////////////////////////////////////////////////////

  var bb = new flatbuffers.ByteBuffer(bytes);
  assert.ok(Monster.bufferHasIdentifier(bb));
  var mon = Monster.getRootAsMonster(bb);

  var stat = mon.testempty();
  assert.strictEqual(stat != null, true);
  assert.strictEqual(stat.val() != null, true);
  assert.strictEqual(stat.val(), 2541551405100253985n);

  var mon2 = mon.enemy();
  assert.strictEqual(mon2 != null, true);
  stat = mon2.testempty();
  assert.strictEqual(stat != null, true);
  assert.strictEqual(stat.val() != null, true);
  assert.strictEqual(stat.val(), 0n);  // default value
}

function testUnicode() {
  var correct = fs.readFileSync('../unicode_test.mon');
  var json = JSON.parse(fs.readFileSync('../unicode_test.json', 'utf8'));

  // Test reading
  function testReadingUnicode(bb) {
    var monster = Monster.getRootAsMonster(bb);
    assert.strictEqual(monster.name(), json.name);
    assert.deepEqual(
        Buffer.from(monster.name(flatbuffers.Encoding.UTF8_BYTES)),
        Buffer.from(json.name));
    assert.strictEqual(
        monster.testarrayoftablesLength(), json.testarrayoftables.length);
    json.testarrayoftables.forEach(function(table, i) {
      var value = monster.testarrayoftables(i);
      assert.strictEqual(value.name(), table.name);
      assert.deepEqual(
          Buffer.from(value.name(flatbuffers.Encoding.UTF8_BYTES)),
          Buffer.from(table.name));
    });
    assert.strictEqual(
        monster.testarrayofstringLength(), json.testarrayofstring.length);
    json.testarrayofstring.forEach(function(string, i) {
      assert.strictEqual(monster.testarrayofstring(i), string);
      assert.deepEqual(
          Buffer.from(
              monster.testarrayofstring(i, flatbuffers.Encoding.UTF8_BYTES)),
          Buffer.from(string));
    });
  }
  testReadingUnicode(new flatbuffers.ByteBuffer(new Uint8Array(correct)));

  // Test writing
  var fbb = new flatbuffers.Builder();
  var name = fbb.createString(json.name);
  var testarrayoftablesOffsets = json.testarrayoftables.map(function(table) {
    var name = fbb.createString(new Uint8Array(Buffer.from(table.name)));
    Monster.startMonster(fbb);
    Monster.addName(fbb, name);
    return Monster.endMonster(fbb);
  });
  var testarrayoftablesOffset =
      Monster.createTestarrayoftablesVector(fbb, testarrayoftablesOffsets);
  var testarrayofstringOffset = Monster.createTestarrayofstringVector(
      fbb, json.testarrayofstring.map(function(string) {
        return fbb.createString(string);
      }));
  Monster.startMonster(fbb);
  Monster.addTestarrayofstring(fbb, testarrayofstringOffset);
  Monster.addTestarrayoftables(fbb, testarrayoftablesOffset);
  Monster.addName(fbb, name);
  Monster.finishSizePrefixedMonsterBuffer(fbb, Monster.endMonster(fbb));
  var bb = new flatbuffers.ByteBuffer(fbb.asUint8Array())
  bb.setPosition(4);
  testReadingUnicode(bb);
}

var __imul = Math.imul ? Math.imul : function(a, b) {
  var ah = a >> 16 & 65535;
  var bh = b >> 16 & 65535;
  var al = a & 65535;
  var bl = b & 65535;
  return al * bl + (ah * bl + al * bh << 16) | 0;
};

// Include simple random number generator to ensure results will be the
// same cross platform.
// http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
var lcg_seed = 48271;

function lcg_rand() {
  return lcg_seed = (__imul(lcg_seed, 279470273) >>> 0) % 4294967291;
}

function lcg_reset() {
  lcg_seed = 48271;
}

// Converts a Field ID to a virtual table offset.
function fieldIndexToOffset(field_id) {
  // Should correspond to what EndTable() below builds up.
  var fixed_fields = 2;  // Vtable size and Object Size.
  return (field_id + fixed_fields) * 2;
}

// Low level stress/fuzz test: serialize/deserialize a variety of
// different kinds of data in different combinations
function fuzzTest1() {
  // Values we're testing against: chosen to ensure no bits get chopped
  // off anywhere, and also be different from eachother.
  var bool_val = true;
  var char_val = -127;  // 0x81
  var uchar_val = 0xFF;
  var short_val = -32222;  // 0x8222;
  var ushort_val = 0xFEEE;
  var int_val = 0x83333333 | 0;
  var uint_val = 0xFDDDDDDD;
  var long_val = BigInt.asIntN(64, 0x8444444444444444n);
  var ulong_val = BigInt.asUintN(64, 0xFCCCCCCCCCCCCCCCn);
  var float_val = new Float32Array([3.14159])[0];
  var double_val = 3.14159265359;

  var test_values_max = 11;
  var fields_per_object = 4;
  var num_fuzz_objects = 10000;  // The higher, the more thorough :)

  var builder = new flatbuffers.Builder();

  lcg_reset();  // Keep it deterministic.

  var objects = [];

  // Generate num_fuzz_objects random objects each consisting of
  // fields_per_object fields, each of a random type.
  for (var i = 0; i < num_fuzz_objects; i++) {
    builder.startObject(fields_per_object);
    for (var f = 0; f < fields_per_object; f++) {
      var choice = lcg_rand() % test_values_max;
      switch (choice) {
        case 0:
          builder.addFieldInt8(f, bool_val, 0);
          break;
        case 1:
          builder.addFieldInt8(f, char_val, 0);
          break;
        case 2:
          builder.addFieldInt8(f, uchar_val, 0);
          break;
        case 3:
          builder.addFieldInt16(f, short_val, 0);
          break;
        case 4:
          builder.addFieldInt16(f, ushort_val, 0);
          break;
        case 5:
          builder.addFieldInt32(f, int_val, 0);
          break;
        case 6:
          builder.addFieldInt32(f, uint_val, 0);
          break;
        case 7:
          builder.addFieldInt64(f, long_val, 0n);
          break;
        case 8:
          builder.addFieldInt64(f, ulong_val, 0n);
          break;
        case 9:
          builder.addFieldFloat32(f, float_val, 0);
          break;
        case 10:
          builder.addFieldFloat64(f, double_val, 0);
          break;
      }
    }
    objects.push(builder.endObject());
  }
  builder.prep(8, 0);  // Align whole buffer.

  lcg_reset();  // Reset.

  builder.finish(objects[objects.length - 1]);
  var bytes = new Uint8Array(builder.asUint8Array());
  var view = new DataView(bytes.buffer);

  // Test that all objects we generated are readable and return the
  // expected values. We generate random objects in the same order
  // so this is deterministic.
  for (var i = 0; i < num_fuzz_objects; i++) {
    var offset = bytes.length - objects[i];
    for (var f = 0; f < fields_per_object; f++) {
      var choice = lcg_rand() % test_values_max;
      var vtable_offset = fieldIndexToOffset(f);
      var vtable = offset - view.getInt32(offset, true);
      assert.ok(vtable_offset < view.getInt16(vtable, true));
      var field_offset = offset + view.getInt16(vtable + vtable_offset, true);
      switch (choice) {
        case 0:
          assert.strictEqual(!!view.getInt8(field_offset), bool_val);
          break;
        case 1:
          assert.strictEqual(view.getInt8(field_offset), char_val);
          break;
        case 2:
          assert.strictEqual(view.getUint8(field_offset), uchar_val);
          break;
        case 3:
          assert.strictEqual(view.getInt16(field_offset, true), short_val);
          break;
        case 4:
          assert.strictEqual(view.getUint16(field_offset, true), ushort_val);
          break;
        case 5:
          assert.strictEqual(view.getInt32(field_offset, true), int_val);
          break;
        case 6:
          assert.strictEqual(view.getUint32(field_offset, true), uint_val);
          break;
        case 7:
          assert.strictEqual(view.getBigInt64(field_offset, true), long_val);
          break;
        case 8:
          assert.strictEqual(view.getBigUint64(field_offset, true), ulong_val);
          break;
        case 9:
          assert.strictEqual(view.getFloat32(field_offset, true), float_val);
          break;
        case 10:
          assert.strictEqual(view.getFloat64(field_offset, true), double_val);
          break;
      }
    }
  }
}

function testSharedStrings() {
  var shared_string = 'Hello world';
  var builder = new flatbuffers.Builder();
  let mainOffset = builder.createSharedString(shared_string);
  assert.strictEqual(builder.createSharedString(shared_string), mainOffset);
}

function testNullStrings() {
  var builder = new flatbuffers.Builder();
  assert.strictEqual(builder.createString(null), 0);
  assert.strictEqual(builder.createSharedString(null), 0);
  assert.strictEqual(builder.createString(undefined), 0);
  assert.strictEqual(builder.createSharedString(undefined), 0);
}

function testVectorOfStructs() {
  let monster = new MonsterT();
  monster.name = 'testVectorOfStructs';
  monster.test4 = [new TestT(1, 2), new TestT(3, 4)];

  let builder = new flatbuffers.Builder();
  builder.finish(monster.pack(builder));

  let decodedMonster = Monster.getRootAsMonster(builder.dataBuffer()).unpack();
  assert.strictEqual(decodedMonster.test4[0].a, 1);
  assert.strictEqual(decodedMonster.test4[0].b, 2);
  assert.strictEqual(decodedMonster.test4[1].a, 3);
  assert.strictEqual(decodedMonster.test4[1].b, 4);
}

function testCreateByteVector() {
  const data = Uint8Array.from([1, 2, 3, 4, 5]);

  const builder = new flatbuffers.Builder();
  const required = builder.createString('required');
  const offset = builder.createByteVector(data);

  Monster.startMonster(builder);
  Monster.addName(builder, required);
  Monster.addInventory(builder, offset)
  builder.finish(Monster.endMonster(builder));

  let decodedMonster = Monster.getRootAsMonster(builder.dataBuffer());
  assert.deepEqual(decodedMonster.inventoryArray(), data);
}

main();
