// Copyright (c) 2012 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 "build/build_config.h"

#if defined(OS_WIN)
#include <windows.h>
#endif

#include <string>

#include "base/message_loop/message_loop.h"
#include "base/pickle.h"
#include "base/threading/thread.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_test_base.h"
#include "ipc/ipc_test_channel_listener.h"

namespace {

class IPCChannelTest : public IPCTestBase {
};

// TODO(viettrungluu): Move to a separate IPCMessageTest.
TEST_F(IPCChannelTest, BasicMessageTest) {
  int v1 = 10;
  std::string v2("foobar");
  std::wstring v3(L"hello world");

  IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
  EXPECT_TRUE(m.WriteInt(v1));
  EXPECT_TRUE(m.WriteString(v2));
  EXPECT_TRUE(m.WriteWString(v3));

  PickleIterator iter(m);

  int vi;
  std::string vs;
  std::wstring vw;

  EXPECT_TRUE(m.ReadInt(&iter, &vi));
  EXPECT_EQ(v1, vi);

  EXPECT_TRUE(m.ReadString(&iter, &vs));
  EXPECT_EQ(v2, vs);

  EXPECT_TRUE(m.ReadWString(&iter, &vw));
  EXPECT_EQ(v3, vw);

  // should fail
  EXPECT_FALSE(m.ReadInt(&iter, &vi));
  EXPECT_FALSE(m.ReadString(&iter, &vs));
  EXPECT_FALSE(m.ReadWString(&iter, &vw));
}

TEST_F(IPCChannelTest, ChannelTest) {
  Init("GenericClient");

  // Set up IPC channel and start client.
  IPC::TestChannelListener listener;
  CreateChannel(&listener);
  listener.Init(sender());
  ASSERT_TRUE(ConnectChannel());
  ASSERT_TRUE(StartClient());

  IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");

  // Run message loop.
  base::MessageLoop::current()->Run();

  // Close the channel so the client's OnChannelError() gets fired.
  channel()->Close();

  EXPECT_TRUE(WaitForClientShutdown());
  DestroyChannel();
}

// TODO(viettrungluu): Move to a separate IPCChannelWinTest.
#if defined(OS_WIN)
TEST_F(IPCChannelTest, ChannelTestExistingPipe) {
  Init("GenericClient");

  // Create pipe manually using the standard Chromium name and set up IPC
  // channel.
  IPC::TestChannelListener listener;
  std::string name("\\\\.\\pipe\\chrome.");
  name.append(GetChannelName("GenericClient"));
  HANDLE pipe = CreateNamedPipeA(name.c_str(),
                                 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
                                     FILE_FLAG_FIRST_PIPE_INSTANCE,
                                 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
                                 1,
                                 4096,
                                 4096,
                                 5000,
                                 NULL);
  CreateChannelFromChannelHandle(IPC::ChannelHandle(pipe), &listener);
  CloseHandle(pipe);  // The channel duplicates the handle.
  listener.Init(sender());

  // Connect to channel and start client.
  ASSERT_TRUE(ConnectChannel());
  ASSERT_TRUE(StartClient());

  IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");

  // Run message loop.
  base::MessageLoop::current()->Run();

  // Close the channel so the client's OnChannelError() gets fired.
  channel()->Close();

  EXPECT_TRUE(WaitForClientShutdown());
  DestroyChannel();
}
#endif  // defined (OS_WIN)

TEST_F(IPCChannelTest, ChannelProxyTest) {
  Init("GenericClient");

  base::Thread thread("ChannelProxyTestServer");
  base::Thread::Options options;
  options.message_loop_type = base::MessageLoop::TYPE_IO;
  thread.StartWithOptions(options);

  // Set up IPC channel proxy.
  IPC::TestChannelListener listener;
  CreateChannelProxy(&listener, thread.message_loop_proxy().get());
  listener.Init(sender());

  ASSERT_TRUE(StartClient());

  IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");

  // Run message loop.
  base::MessageLoop::current()->Run();

  EXPECT_TRUE(WaitForClientShutdown());

  // Destroy the channel proxy before shutting down the thread.
  DestroyChannelProxy();
  thread.Stop();
}

class ChannelListenerWithOnConnectedSend : public IPC::TestChannelListener {
 public:
  ChannelListenerWithOnConnectedSend() {}
  virtual ~ChannelListenerWithOnConnectedSend() {}

  virtual void OnChannelConnected(int32 peer_pid) OVERRIDE {
    SendNextMessage();
  }
};

#if defined(OS_WIN)
// Acting flakey in Windows. http://crbug.com/129595
#define MAYBE_SendMessageInChannelConnected DISABLED_SendMessageInChannelConnected
#else
#define MAYBE_SendMessageInChannelConnected SendMessageInChannelConnected
#endif
// This tests the case of a listener sending back an event in its
// OnChannelConnected handler.
TEST_F(IPCChannelTest, MAYBE_SendMessageInChannelConnected) {
  Init("GenericClient");

  // Set up IPC channel and start client.
  ChannelListenerWithOnConnectedSend listener;
  CreateChannel(&listener);
  listener.Init(sender());
  ASSERT_TRUE(ConnectChannel());
  ASSERT_TRUE(StartClient());

  IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");

  // Run message loop.
  base::MessageLoop::current()->Run();

  // Close the channel so the client's OnChannelError() gets fired.
  channel()->Close();

  EXPECT_TRUE(WaitForClientShutdown());
  DestroyChannel();
}

MULTIPROCESS_IPC_TEST_CLIENT_MAIN(GenericClient) {
  base::MessageLoopForIO main_message_loop;
  IPC::TestChannelListener listener;

  // Set up IPC channel.
  scoped_ptr<IPC::Channel> channel(IPC::Channel::CreateClient(
      IPCTestBase::GetChannelName("GenericClient"),
      &listener));
  CHECK(channel->Connect());
  listener.Init(channel.get());
  IPC::TestChannelListener::SendOneMessage(channel.get(), "hello from child");

  base::MessageLoop::current()->Run();
  return 0;
}

}  // namespace
