// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

define('mojo/edk/js/tests/js_to_cpp_tests', [
  'console',
  'mojo/edk/js/tests/js_to_cpp.mojom',
  'mojo/public/js/connection',
  'mojo/public/js/connector',
  'mojo/public/js/core',
], function (console, jsToCpp, connection, connector, core) {
  var retainedConnection;
  var sampleData;
  var sampleMessage;
  var BAD_VALUE = 13;
  var DATA_PIPE_PARAMS = {
    flags: core.CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
    elementNumBytes: 1,
    capacityNumBytes: 64
  };

  function JsSideConnection() {
  }

  JsSideConnection.prototype =
      Object.create(jsToCpp.JsSide.stubClass.prototype);

  JsSideConnection.prototype.ping = function (arg) {
    this.cppSide_.pingResponse();
  };

  JsSideConnection.prototype.echo = function (numIterations, arg) {
    var dataPipe1;
    var dataPipe2;
    var i;
    var messagePipe1;
    var messagePipe2;
    var specialArg;

    // Ensure expected negative values are negative.
    if (arg.si64 > 0)
      arg.si64 = BAD_VALUE;

    if (arg.si32 > 0)
      arg.si32 = BAD_VALUE;

    if (arg.si16 > 0)
      arg.si16 = BAD_VALUE;

    if (arg.si8 > 0)
      arg.si8 = BAD_VALUE;

    for (i = 0; i < numIterations; ++i) {
      dataPipe1 = core.createDataPipe(DATA_PIPE_PARAMS);
      dataPipe2 = core.createDataPipe(DATA_PIPE_PARAMS);
      messagePipe1 = core.createMessagePipe();
      messagePipe2 = core.createMessagePipe();

      arg.data_handle = dataPipe1.consumerHandle;
      arg.message_handle = messagePipe1.handle1;

      specialArg = new jsToCpp.EchoArgs();
      specialArg.si64 = -1;
      specialArg.si32 = -1;
      specialArg.si16 = -1;
      specialArg.si8 = -1;
      specialArg.name = 'going';
      specialArg.data_handle = dataPipe2.consumerHandle;
      specialArg.message_handle = messagePipe2.handle1;

      writeDataPipe(dataPipe1, sampleData);
      writeDataPipe(dataPipe2, sampleData);
      writeMessagePipe(messagePipe1, sampleMessage);
      writeMessagePipe(messagePipe2, sampleMessage);

      this.cppSide_.echoResponse(createEchoArgsList(specialArg, arg));

      core.close(dataPipe1.producerHandle);
      core.close(dataPipe2.producerHandle);
      core.close(messagePipe1.handle0);
      core.close(messagePipe2.handle0);
    }
    this.cppSide_.testFinished();
  };

  JsSideConnection.prototype.bitFlip = function (arg) {
    var iteration = 0;
    var dataPipe;
    var messagePipe;
    var proto = connector.Connector.prototype;
    var stopSignalled = false;

    proto.realAccept = proto.accept;
    proto.accept = function (message) {
      var offset = iteration / 8;
      var mask;
      var value;
      if (offset < message.buffer.arrayBuffer.byteLength) {
        mask = 1 << (iteration % 8);
        value = message.buffer.getUint8(offset) ^ mask;
        message.buffer.setUint8(offset, value);
        return this.realAccept(message);
      }
      stopSignalled = true;
      return false;
    };

    while (!stopSignalled) {
      dataPipe = core.createDataPipe(DATA_PIPE_PARAMS);
      messagePipe = core.createMessagePipe();
      writeDataPipe(dataPipe, sampleData);
      writeMessagePipe(messagePipe, sampleMessage);
      arg.data_handle = dataPipe.consumerHandle;
      arg.message_handle = messagePipe.handle1;

      this.cppSide_.bitFlipResponse(createEchoArgsList(arg));

      core.close(dataPipe.producerHandle);
      core.close(messagePipe.handle0);
      iteration += 1;
    }

    proto.accept = proto.realAccept;
    proto.realAccept = null;
    this.cppSide_.testFinished();
  };

  JsSideConnection.prototype.backPointer = function (arg) {
    var iteration = 0;
    var dataPipe;
    var messagePipe;
    var proto = connector.Connector.prototype;
    var stopSignalled = false;

    proto.realAccept = proto.accept;
    proto.accept = function (message) {
      var delta = 8 * (1 + iteration % 32);
      var offset = 8 * ((iteration / 32) | 0);
      if (offset < message.buffer.arrayBuffer.byteLength - 4) {
        message.buffer.dataView.setUint32(offset, 0x100000000 - delta, true);
        message.buffer.dataView.setUint32(offset + 4, 0xffffffff, true);
        return this.realAccept(message);
      }
      stopSignalled = true;
      return false;
    };

    while (!stopSignalled) {
      dataPipe = core.createDataPipe(DATA_PIPE_PARAMS);
      messagePipe = core.createMessagePipe();
      writeDataPipe(dataPipe, sampleData);
      writeMessagePipe(messagePipe, sampleMessage);
      arg.data_handle = dataPipe.consumerHandle;
      arg.message_handle = messagePipe.handle1;

      this.cppSide_.backPointerResponse(createEchoArgsList(arg));

      core.close(dataPipe.producerHandle);
      core.close(messagePipe.handle0);
      iteration += 1;
    }

    proto.accept = proto.realAccept;
    proto.realAccept = null;
    this.cppSide_.testFinished();
  };

  function writeDataPipe(pipe, data) {
    var writeResult = core.writeData(
      pipe.producerHandle, data, core.WRITE_DATA_FLAG_ALL_OR_NONE);

    if (writeResult.result != core.RESULT_OK) {
      console.log('ERROR: Data pipe write result was ' + writeResult.result);
      return false;
    }
    if (writeResult.numBytes != data.length) {
      console.log('ERROR: Data pipe write length was ' + writeResult.numBytes);
      return false;
    }
    return true;
  }

  function writeMessagePipe(pipe, arrayBuffer) {
    var result = core.writeMessage(pipe.handle0, arrayBuffer, [], 0);
    if (result != core.RESULT_OK) {
      console.log('ERROR: Message pipe write result was ' + result);
      return false;
    }
    return true;
  }

  function createEchoArgsListElement(item, next) {
    var list = new jsToCpp.EchoArgsList();
    list.item = item;
    list.next = next;
    return list;
  }

  function createEchoArgsList() {
    var genuineArray = Array.prototype.slice.call(arguments);
    return genuineArray.reduceRight(function (previous, current) {
      return createEchoArgsListElement(current, previous);
    }, null);
  }

  function createCppSideConnection(handle, stubClass, proxyClass) {
    var c = new connection.Connection(handle, stubClass, proxyClass);
    c.local.cppSide_ = c.remote;
    return c;
  }

  return function(handle) {
    var i;
    sampleData = new Uint8Array(DATA_PIPE_PARAMS.capacityNumBytes);
    for (i = 0; i < sampleData.length; ++i) {
      sampleData[i] = i;
    }
    sampleMessage = new Uint8Array(DATA_PIPE_PARAMS.capacityNumBytes);
    for (i = 0; i < sampleMessage.length; ++i) {
      sampleMessage[i] = 255 - i;
    }
    retainedConnection = createCppSideConnection(
        handle, JsSideConnection,jsToCpp.CppSide.proxyClass);
    retainedConnection.remote.startTest();
  };
});
