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

#include "ipc/ipc_test_base.h"

#include "base/command_line.h"
#include "base/debug/debug_on_start_win.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "ipc/ipc_descriptors.h"
#include "ipc/ipc_switches.h"

// static
std::string IPCTestBase::GetChannelName(const std::string& test_client_name) {
  DCHECK(!test_client_name.empty());
  return test_client_name + "__Channel";
}

IPCTestBase::IPCTestBase()
    : client_process_(base::kNullProcessHandle) {
}

IPCTestBase::~IPCTestBase() {
}

void IPCTestBase::SetUp() {
  MultiProcessTest::SetUp();

  // Construct a fresh IO Message loop for the duration of each test.
  DCHECK(!message_loop_.get());
  message_loop_.reset(new base::MessageLoopForIO());
}

void IPCTestBase::TearDown() {
  DCHECK(message_loop_.get());
  message_loop_.reset();
  MultiProcessTest::TearDown();
}

void IPCTestBase::Init(const std::string& test_client_name) {
  DCHECK(!test_client_name.empty());
  DCHECK(test_client_name_.empty());
  test_client_name_ = test_client_name;
}

void IPCTestBase::CreateChannel(IPC::Listener* listener) {
  return CreateChannelFromChannelHandle(GetChannelName(test_client_name_),
                                        listener);
}

bool IPCTestBase::ConnectChannel() {
  CHECK(channel_.get());
  return channel_->Connect();
}

void IPCTestBase::DestroyChannel() {
  DCHECK(channel_.get());
  channel_.reset();
}

void IPCTestBase::CreateChannelFromChannelHandle(
    const IPC::ChannelHandle& channel_handle,
    IPC::Listener* listener) {
  CHECK(!channel_.get());
  CHECK(!channel_proxy_.get());
  channel_.reset(new IPC::Channel(channel_handle,
                                  IPC::Channel::MODE_SERVER,
                                  listener));
}

void IPCTestBase::CreateChannelProxy(
    IPC::Listener* listener,
    base::SingleThreadTaskRunner* ipc_task_runner) {
  CHECK(!channel_.get());
  CHECK(!channel_proxy_.get());
  channel_proxy_.reset(new IPC::ChannelProxy(GetChannelName(test_client_name_),
                                             IPC::Channel::MODE_SERVER,
                                             listener,
                                             ipc_task_runner));
}

void IPCTestBase::DestroyChannelProxy() {
  CHECK(channel_proxy_.get());
  channel_proxy_.reset();
}

bool IPCTestBase::StartClient() {
  DCHECK(client_process_ == base::kNullProcessHandle);

  std::string test_main = test_client_name_ + "TestClientMain";
  bool debug_on_start =
      CommandLine::ForCurrentProcess()->HasSwitch(switches::kDebugChildren);

#if defined(OS_WIN)
  client_process_ = MultiProcessTest::SpawnChild(test_main, debug_on_start);
#elif defined(OS_POSIX)
  base::FileHandleMappingVector fds_to_map;
  const int ipcfd = channel_.get() ? channel_->GetClientFileDescriptor() :
                                     channel_proxy_->GetClientFileDescriptor();
  if (ipcfd > -1)
    fds_to_map.push_back(std::pair<int, int>(ipcfd, kPrimaryIPCChannel + 3));

  client_process_ = MultiProcessTest::SpawnChild(test_main,
                                                 fds_to_map,
                                                 debug_on_start);
#endif

  return client_process_ != base::kNullProcessHandle;
}

bool IPCTestBase::WaitForClientShutdown() {
  DCHECK(client_process_ != base::kNullProcessHandle);

  bool rv = base::WaitForSingleProcess(client_process_,
                                       base::TimeDelta::FromSeconds(5));
  base::CloseProcessHandle(client_process_);
  client_process_ = base::kNullProcessHandle;
  return rv;
}
