// 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_(base::WaitableEvent::ResetPolicy::MANUAL,
               base::WaitableEvent::InitialState::NOT_SIGNALED),
        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::SpawnChildResult LaunchTestChild(const std::string& function,
                                         int child_process_id) {
    base::AutoLock lock(broker_.GetLock());
    base::SpawnChildResult spawn_child = base::SpawnMultiProcessTestChild(
        function, base::GetMultiProcessTestChildBaseCommandLine(),
        base::LaunchOptions());
    broker_.AddPlaceholderForPid(spawn_child.process.Handle(),
                                 child_process_id);
    return spawn_child;
  }

  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::SpawnChildResult spawn_child =
      LaunchTestChild("MachBrokerTestChild", 7);
  WaitForTaskPort();
  EXPECT_EQ(spawn_child.process.Handle(), received_process_);
  WaitForChildExit(spawn_child.process);

  EXPECT_NE(static_cast<mach_port_t>(MACH_PORT_NULL),
            broker_.TaskForPid(spawn_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(spawn_child.process.Handle() + 1));

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

}  // namespace content
