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

#include <stdlib.h>
#include <string.h>

#include "mojo/public/bindings/lib/bindings_support.h"
#include "mojo/public/bindings/lib/connector.h"
#include "mojo/public/bindings/lib/message_queue.h"
#include "mojo/public/system/macros.h"
#include "mojo/public/tests/simple_bindings_support.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace mojo {
namespace test {

class MessageAccumulator : public MessageReceiver {
 public:
  MessageAccumulator() {
  }

  virtual bool Accept(Message* message) MOJO_OVERRIDE {
    queue_.Push(message);
    return true;
  }

  bool IsEmpty() const {
    return queue_.IsEmpty();
  }

  void Pop(Message* message) {
    queue_.Pop(message);
  }

 private:
  MessageQueue queue_;
};

class BindingsConnectorTest : public testing::Test {
 public:
  BindingsConnectorTest() {
  }

  virtual void SetUp() MOJO_OVERRIDE {
    CreateMessagePipe(&handle0_, &handle1_);
  }

  virtual void TearDown() MOJO_OVERRIDE {
  }

  void AllocMessage(const char* text, Message* message) {
    size_t payload_size = strlen(text) + 1;  // Plus null terminator.
    size_t num_bytes = sizeof(MessageHeader) + payload_size;
    message->data = static_cast<MessageData*>(malloc(num_bytes));
    message->data->header.num_bytes = static_cast<uint32_t>(num_bytes);
    message->data->header.name = 1;
    memcpy(message->data->payload, text, payload_size);
  }

  void PumpMessages() {
    bindings_support_.Process();
  }

 protected:
  ScopedMessagePipeHandle handle0_;
  ScopedMessagePipeHandle handle1_;

 private:
  SimpleBindingsSupport bindings_support_;
};

TEST_F(BindingsConnectorTest, Basic) {
  internal::Connector connector0(handle0_.Pass());
  internal::Connector connector1(handle1_.Pass());

  const char kText[] = "hello world";

  Message message;
  AllocMessage(kText, &message);

  connector0.Accept(&message);

  MessageAccumulator accumulator;
  connector1.SetIncomingReceiver(&accumulator);

  PumpMessages();

  ASSERT_FALSE(accumulator.IsEmpty());

  Message message_received;
  accumulator.Pop(&message_received);

  EXPECT_EQ(std::string(kText),
            std::string(
                reinterpret_cast<char*>(message_received.data->payload)));
}

TEST_F(BindingsConnectorTest, Basic_EarlyIncomingReceiver) {
  internal::Connector connector0(handle0_.Pass());
  internal::Connector connector1(handle1_.Pass());

  MessageAccumulator accumulator;
  connector1.SetIncomingReceiver(&accumulator);

  const char kText[] = "hello world";

  Message message;
  AllocMessage(kText, &message);

  connector0.Accept(&message);

  PumpMessages();

  ASSERT_FALSE(accumulator.IsEmpty());

  Message message_received;
  accumulator.Pop(&message_received);

  EXPECT_EQ(std::string(kText),
            std::string(
                reinterpret_cast<char*>(message_received.data->payload)));
}

TEST_F(BindingsConnectorTest, Basic_TwoMessages) {
  internal::Connector connector0(handle0_.Pass());
  internal::Connector connector1(handle1_.Pass());

  const char* kText[] = { "hello", "world" };

  for (size_t i = 0; i < MOJO_ARRAYSIZE(kText); ++i) {
    Message message;
    AllocMessage(kText[i], &message);

    connector0.Accept(&message);
  }

  MessageAccumulator accumulator;
  connector1.SetIncomingReceiver(&accumulator);

  PumpMessages();

  for (size_t i = 0; i < MOJO_ARRAYSIZE(kText); ++i) {
    ASSERT_FALSE(accumulator.IsEmpty());

    Message message_received;
    accumulator.Pop(&message_received);

    EXPECT_EQ(std::string(kText[i]),
              std::string(
                  reinterpret_cast<char*>(message_received.data->payload)));
  }
}

TEST_F(BindingsConnectorTest, WriteToClosedPipe) {
  // Leak this, so the closed handle isn't closed again.
  MojoHandle mojo_handle = handle0_.get().value();
  internal::Connector* connector0 = new internal::Connector(handle0_.Pass());

  const char kText[] = "hello world";

  Message message;
  AllocMessage(kText, &message);

  // Close handle out from under the connection
  MojoClose(mojo_handle);

  bool ok = connector0->Accept(&message);
  EXPECT_FALSE(ok);

  EXPECT_TRUE(connector0->encountered_error());
}

// Enable this test once MojoWriteMessage supports passing handles.
TEST_F(BindingsConnectorTest, MessageWithHandles) {
  internal::Connector connector0(handle0_.Pass());
  internal::Connector connector1(handle1_.Pass());

  const char kText[] = "hello world";

  Message message;
  AllocMessage(kText, &message);

  ScopedMessagePipeHandle handles[2];
  CreateMessagePipe(&handles[0], &handles[1]);
  message.handles.push_back(handles[0].release());

  connector0.Accept(&message);

  // The message should have been transferred, releasing the handles.
  EXPECT_TRUE(message.handles.empty());

  MessageAccumulator accumulator;
  connector1.SetIncomingReceiver(&accumulator);

  PumpMessages();

  ASSERT_FALSE(accumulator.IsEmpty());

  Message message_received;
  accumulator.Pop(&message_received);

  EXPECT_EQ(std::string(kText),
            std::string(
                reinterpret_cast<char*>(message_received.data->payload)));
  ASSERT_EQ(1U, message_received.handles.size());

  // Now send a message to the transferred handle and confirm it's sent through
  // to the orginal pipe.
  // TODO(vtl): Do we need a better way of "downcasting" the handle types?
  ScopedMessagePipeHandle smph;
  smph.reset(MessagePipeHandle(message_received.handles[0].value()));
  message_received.handles[0] = Handle();  // |smph| now owns this handle.

  internal::Connector connector_received(smph.Pass());
  internal::Connector connector_original(handles[1].Pass());

  AllocMessage(kText, &message);

  connector_received.Accept(&message);
  connector_original.SetIncomingReceiver(&accumulator);
  PumpMessages();

  ASSERT_FALSE(accumulator.IsEmpty());

  accumulator.Pop(&message_received);

  EXPECT_EQ(std::string(kText),
            std::string(
                reinterpret_cast<char*>(message_received.data->payload)));
}

}  // namespace test
}  // namespace mojo
