// Copyright (c) 2009 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 "content/browser/mach_broker_mac.h"

#include "base/command_line.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/multiprocess_test.h"
#include "base/test/test_timeouts.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"

namespace content {

class MachBrokerTest : public testing::Test,
                       public base::PortProvider::Observer {
 public:
  MachBrokerTest()
      : event_(true, false), received_process_(base::kNullProcessHandle) {
    broker_.AddObserver(this);
  }
  ~MachBrokerTest() override {
    broker_.RemoveObserver(this);
  }

  // Helper function to acquire/release locks and call |PlaceholderForPid()|.
  void AddPlaceholderForPid(base::ProcessHandle pid, int child_process_id) {
    base::AutoLock lock(broker_.GetLock());
    broker_.AddPlaceholderForPid(pid, child_process_id);
  }

  void InvalidateChildProcessId(int child_process_id) {
    broker_.InvalidateChildProcessId(child_process_id);
  }

  int GetChildProcessCount(int child_process_id) {
    return broker_.child_process_id_map_.count(child_process_id);
  }

  base::Process LaunchTestChild(const std::string& function,
                                int child_process_id) {
    base::AutoLock lock(broker_.GetLock());
    base::Process test_child_process = base::SpawnMultiProcessTestChild(
        function, base::GetMultiProcessTestChildBaseCommandLine(),
        base::LaunchOptions());
    broker_.AddPlaceholderForPid(test_child_process.Handle(), child_process_id);
    return test_child_process;
  }

  void WaitForChildExit(base::Process& process) {
    int rv = -1;
    ASSERT_TRUE(process.WaitForExitWithTimeout(
                TestTimeouts::action_timeout(), &rv));
    EXPECT_EQ(0, rv);
  }

  void WaitForTaskPort() {
    event_.Wait();
  }

  // base::PortProvider::Observer:
  void OnReceivedTaskPort(base::ProcessHandle process) override {
    received_process_ = process;
    event_.Signal();
  }

 protected:
  MachBroker broker_;
  base::WaitableEvent event_;
  base::ProcessHandle received_process_;
  TestBrowserThreadBundle thread_bundle_;
};

MULTIPROCESS_TEST_MAIN(MachBrokerTestChild) {
  CHECK(MachBroker::ChildSendTaskPortToParent());
  return 0;
}

TEST_F(MachBrokerTest, Locks) {
  // Acquire and release the locks.  Nothing bad should happen.
  base::AutoLock lock(broker_.GetLock());
}

TEST_F(MachBrokerTest, AddChildProcess) {
  {
    base::AutoLock lock(broker_.GetLock());
    broker_.EnsureRunning();
  }
  base::Process child_process = LaunchTestChild("MachBrokerTestChild", 7);
  WaitForTaskPort();
  EXPECT_EQ(child_process.Handle(), received_process_);
  WaitForChildExit(child_process);

  EXPECT_NE(static_cast<mach_port_t>(MACH_PORT_NULL),
            broker_.TaskForPid(child_process.Handle()));
  EXPECT_EQ(1, GetChildProcessCount(7));

  // Should be no entry for any other PID.
  EXPECT_EQ(static_cast<mach_port_t>(MACH_PORT_NULL),
            broker_.TaskForPid(child_process.Handle() + 1));

  InvalidateChildProcessId(7);
  EXPECT_EQ(static_cast<mach_port_t>(MACH_PORT_NULL),
            broker_.TaskForPid(child_process.Handle()));
  EXPECT_EQ(0, GetChildProcessCount(7));
}

}  // namespace content
