// Copyright 2013 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.

// Mock out the support module to avoid depending on the message loop.
define("mojo/public/js/bindings/support", ["timer"], function(timer) {
  var waitingCallbacks = [];

  function WaitCookie(id) {
    this.id = id;
  }

  function asyncWait(handle, flags, callback) {
    var id = waitingCallbacks.length;
    waitingCallbacks.push(callback);
    return new WaitCookie(id);
  }

  function cancelWait(cookie) {
    waitingCallbacks[cookie.id] = null;
  }

  function numberOfWaitingCallbacks() {
    var count = 0;
    for (var i = 0; i < waitingCallbacks.length; ++i) {
      if (waitingCallbacks[i])
        ++count;
    }
    return count;
  }

  function pumpOnce(result) {
    var callbacks = waitingCallbacks;
    waitingCallbacks = [];
    for (var i = 0; i < callbacks.length; ++i) {
      if (callbacks[i])
        callbacks[i](result);
    }
  }

  // Queue up a pumpOnce call to execute after the stack unwinds. Use
  // this to trigger a pump after all Promises are executed.
  function queuePump(result) {
    timer.createOneShot(0, pumpOnce.bind(undefined, result));
  }

  var exports = {};
  exports.asyncWait = asyncWait;
  exports.cancelWait = cancelWait;
  exports.numberOfWaitingCallbacks = numberOfWaitingCallbacks;
  exports.pumpOnce = pumpOnce;
  exports.queuePump = queuePump;
  return exports;
});

define([
    "gin/test/expect",
    "mojo/public/js/bindings/support",
    "mojo/public/js/bindings/core",
    "mojo/public/js/bindings/connection",
    "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom",
    "mojo/public/interfaces/bindings/tests/sample_service.mojom",
    "mojo/apps/js/bindings/threading",
    "gc",
], function(expect,
            mockSupport,
            core,
            connection,
            sample_interfaces,
            sample_service,
            threading,
            gc) {
  testClientServer();
  testWriteToClosedPipe();
  testRequestResponse().then(function() {
    this.result = "PASS";
    gc.collectGarbage();  // should not crash
    threading.quit();
  }.bind(this)).catch(function(e) {
    this.result = "FAIL: " + (e.stack || e);
    threading.quit();
  }.bind(this));

  function testClientServer() {
    var receivedFrobinate = false;
    var receivedDidFrobinate = false;

    // ServiceImpl ------------------------------------------------------------

    function ServiceImpl(peer) {
      this.peer = peer;
    }

    ServiceImpl.prototype = Object.create(
        sample_service.Service.stubClass.prototype);

    ServiceImpl.prototype.frobinate = function(foo, baz, port) {
      receivedFrobinate = true;

      expect(foo.name).toBe("Example name");
      expect(baz).toBeTruthy();
      expect(core.close(port)).toBe(core.RESULT_OK);

      this.peer.didFrobinate(42);
    };

    // ServiceClientImpl ------------------------------------------------------

    function ServiceClientImpl(peer) {
      this.peer = peer;
    }

    ServiceClientImpl.prototype =
        Object.create(sample_service.ServiceClient.stubClass.prototype);

    ServiceClientImpl.prototype.didFrobinate = function(result) {
      receivedDidFrobinate = true;

      expect(result).toBe(42);
    };

    var pipe = core.createMessagePipe();
    var anotherPipe = core.createMessagePipe();
    var sourcePipe = core.createMessagePipe();

    var connection0 = new connection.Connection(
        pipe.handle0, ServiceImpl, sample_service.ServiceClient.proxyClass);

    var connection1 = new connection.Connection(
        pipe.handle1, ServiceClientImpl, sample_service.Service.proxyClass);

    var foo = new sample_service.Foo();
    foo.bar = new sample_service.Bar();
    foo.name = "Example name";
    foo.source = sourcePipe.handle0;
    connection1.remote.frobinate(foo, true, anotherPipe.handle0);

    mockSupport.pumpOnce(core.RESULT_OK);

    expect(receivedFrobinate).toBeTruthy();
    expect(receivedDidFrobinate).toBeTruthy();

    connection0.close();
    connection1.close();

    expect(mockSupport.numberOfWaitingCallbacks()).toBe(0);

    // sourcePipe.handle0 was closed automatically when sent over IPC.
    expect(core.close(sourcePipe.handle0)).toBe(core.RESULT_INVALID_ARGUMENT);
    // sourcePipe.handle1 hasn't been closed yet.
    expect(core.close(sourcePipe.handle1)).toBe(core.RESULT_OK);

    // anotherPipe.handle0 was closed automatically when sent over IPC.
    expect(core.close(anotherPipe.handle0)).toBe(core.RESULT_INVALID_ARGUMENT);
    // anotherPipe.handle1 hasn't been closed yet.
    expect(core.close(anotherPipe.handle1)).toBe(core.RESULT_OK);

    // The Connection object is responsible for closing these handles.
    expect(core.close(pipe.handle0)).toBe(core.RESULT_INVALID_ARGUMENT);
    expect(core.close(pipe.handle1)).toBe(core.RESULT_INVALID_ARGUMENT);
  }

  function testWriteToClosedPipe() {
    var pipe = core.createMessagePipe();

    var connection1 = new connection.Connection(
        pipe.handle1, function() {}, sample_service.Service.proxyClass);

    // Close the other end of the pipe.
    core.close(pipe.handle0);

    // Not observed yet because we haven't pumped events yet.
    expect(connection1.encounteredError()).toBeFalsy();

    var foo = new sample_service.Foo();
    foo.bar = new sample_service.Bar();
    // TODO(darin): crbug.com/357043: pass null in place of |foo| here.
    connection1.remote.frobinate(foo, true, null);

    // Write failures are not reported.
    expect(connection1.encounteredError()).toBeFalsy();

    // Pump events, and then we should start observing the closed pipe.
    mockSupport.pumpOnce(core.RESULT_OK);

    expect(connection1.encounteredError()).toBeTruthy();

    connection1.close();
  }

  function testRequestResponse() {

    // ProviderImpl ------------------------------------------------------------

    function ProviderImpl(peer) {
      this.peer = peer;
    }

    ProviderImpl.prototype =
        Object.create(sample_interfaces.Provider.stubClass.prototype);

    ProviderImpl.prototype.echoString = function(a) {
      mockSupport.queuePump(core.RESULT_OK);
      return Promise.resolve({a: a});
    };

    ProviderImpl.prototype.echoStrings = function(a, b) {
      mockSupport.queuePump(core.RESULT_OK);
      return Promise.resolve({a: a, b: b});
    };

    // ProviderClientImpl ------------------------------------------------------

    function ProviderClientImpl(peer) {
      this.peer = peer;
    }

    ProviderClientImpl.prototype =
        Object.create(sample_interfaces.ProviderClient.stubClass.prototype);

    var pipe = core.createMessagePipe();

    var connection0 = new connection.Connection(
        pipe.handle0,
        ProviderImpl,
        sample_interfaces.ProviderClient.proxyClass);

    var connection1 = new connection.Connection(
        pipe.handle1,
        ProviderClientImpl,
        sample_interfaces.Provider.proxyClass);

    var origReadMessage = core.readMessage;
    // echoString
    mockSupport.queuePump(core.RESULT_OK);
    return connection1.remote.echoString("hello").then(function(response) {
      expect(response.a).toBe("hello");
    }).then(function() {
      // echoStrings
      mockSupport.queuePump(core.RESULT_OK);
      return connection1.remote.echoStrings("hello", "world");
    }).then(function(response) {
      expect(response.a).toBe("hello");
      expect(response.b).toBe("world");
    }).then(function() {
      // Mock a read failure, expect it to fail.
      core.readMessage = function() {
        return { result: core.RESULT_UNKNOWN };
      };
      mockSupport.queuePump(core.RESULT_OK);
      return connection1.remote.echoString("goodbye");
    }).then(function() {
      throw Error("Expected echoString to fail.");
    }, function(error) {
      expect(error.message).toBe("Connection error: " + core.RESULT_UNKNOWN);

      // Clean up.
      core.readMessage = origReadMessage;
    });
  }
});
