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

// Create a service process that uses a Mock to respond to the browser in order
// to test launching the browser using the cloud print policy check command
// line switch.

#include <stdint.h>

#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "base/process/kill.h"
#include "base/process/process.h"
#include "base/rand_util.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "base/task_scheduler/post_task.h"
#include "base/test/multiprocess_test.h"
#include "base/test/test_timeouts.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/default_tick_clock.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "chrome/browser/chrome_content_browser_client.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/service_process/service_process_control.h"
#include "chrome/browser/ui/startup/startup_browser_creator.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/cloud_print/cloud_print_proxy_info.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/service_process_util.h"
#include "chrome/service/cloud_print/cloud_print_message_handler.h"
#include "chrome/service/service_ipc_server.h"
#include "chrome/service/service_process.h"
#include "chrome/test/base/chrome_unit_test_suite.h"
#include "chrome/test/base/test_launcher_utils.h"
#include "chrome/test/base/testing_browser_process.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "content/public/browser/notification_service.h"
#include "content/public/common/content_paths.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "ipc/ipc.mojom.h"
#include "ipc/ipc_channel_mojo.h"
#include "ipc/ipc_channel_proxy.h"
#include "mojo/core/embedder/embedder.h"
#include "mojo/core/embedder/scoped_ipc_support.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
#include "mojo/public/cpp/system/isolated_connection.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"

#if defined(OS_MACOSX)
#include "chrome/common/mac/mock_launchd.h"
#endif

using ::testing::AnyNumber;
using ::testing::Assign;
using ::testing::AtLeast;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::Mock;
using ::testing::Property;
using ::testing::Return;
using ::testing::WithoutArgs;
using ::testing::_;
using content::BrowserThread;

namespace {

enum MockServiceProcessExitCodes {
  kMissingSwitch = 1,
  kInitializationFailure,
  kExpectationsNotMet,
  kShutdownNotGood
};

#if defined(OS_MACOSX)
const char kTestExecutablePath[] = "test-executable-path";
#endif

bool g_good_shutdown = false;

void ShutdownTask() {
  g_good_shutdown = true;
  g_service_process->Shutdown();
}

class TestStartupClientChannelListener : public IPC::Listener {
 public:
  bool OnMessageReceived(const IPC::Message& message) override { return false; }
};

void ConnectAsync(mojo::ScopedMessagePipeHandle handle,
                  mojo::NamedPlatformChannel::ServerName server_name,
                  mojo::IsolatedConnection* mojo_connection) {
  mojo::PlatformChannelEndpoint endpoint =
      mojo::NamedPlatformChannel::ConnectToServer(server_name);
  if (!endpoint.is_valid())
    return;

  mojo::FuseMessagePipes(mojo_connection->Connect(std::move(endpoint)),
                         std::move(handle));
}

const char kProcessChannelID[] = "process-channel-id";

}  // namespace

class TestServiceProcess : public ServiceProcess {
 public:
  TestServiceProcess() { }
  ~TestServiceProcess() override {}

  bool Initialize(base::OnceClosure quit_closure,
                  std::unique_ptr<ServiceProcessState> state);
};

bool TestServiceProcess::Initialize(
    base::OnceClosure quit_closure,
    std::unique_ptr<ServiceProcessState> state) {
  quit_closure_ = std::move(quit_closure);
  service_process_state_ = std::move(state);

  base::Thread::Options options(base::MessageLoop::TYPE_IO, 0);
  io_thread_.reset(new base::Thread("TestServiceProcess_IO"));
  return io_thread_->StartWithOptions(options);
}

// This mocks the service side IPC message handler, allowing us to have a
// minimal service process.
class MockServiceIPCServer : public ServiceIPCServer {
 public:
  static std::string EnabledUserId();

  MockServiceIPCServer(
      ServiceIPCServer::Client* client,
      const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
      base::WaitableEvent* shutdown_event)
      : ServiceIPCServer(client, io_task_runner, shutdown_event) {}

  MOCK_METHOD1(OnChannelConnected, void(int32_t peer_pid));
  MOCK_METHOD0(OnChannelError, void());
  MOCK_METHOD0(ShutDown, void());

  void SetServiceEnabledExpectations();

 private:
  cloud_print::CloudPrintProxyInfo info_;
};

// static
std::string MockServiceIPCServer::EnabledUserId() {
  return std::string("kitteh@canhazcheezburger.cat");
}

void MockServiceIPCServer::SetServiceEnabledExpectations() {
  EXPECT_CALL(*this, OnChannelError()).Times(0);
  EXPECT_CALL(*this, ShutDown())
      .Times(1)
      .WillOnce(DoAll(
          Assign(&g_good_shutdown, true),
          WithoutArgs(Invoke(g_service_process, &::ServiceProcess::Shutdown))));
}

typedef base::Callback<void(MockServiceIPCServer* server)>
    SetExpectationsCallback;

// The return value from this routine is used as the exit code for the mock
// service process. Any non-zero return value will be printed out and can help
// determine the failure.
int CloudPrintMockService_Main(SetExpectationsCallback set_expectations) {
  base::PlatformThread::SetName("Main Thread");
  base::MessageLoopForUI main_message_loop;
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  content::RegisterPathProvider();

  base::FilePath user_data_dir =
      command_line->GetSwitchValuePath(switches::kUserDataDir);
  CHECK(!user_data_dir.empty());
  CHECK(test_launcher_utils::OverrideUserDataDir(user_data_dir));

  base::RunLoop run_loop;
#if defined(OS_MACOSX)
  if (!command_line->HasSwitch(kTestExecutablePath))
    return kMissingSwitch;
  base::FilePath executable_path =
      command_line->GetSwitchValuePath(kTestExecutablePath);
  EXPECT_FALSE(executable_path.empty());
  MockLaunchd mock_launchd(executable_path, main_message_loop.task_runner(),
                           run_loop.QuitClosure(), true, true);
  Launchd::ScopedInstance use_mock(&mock_launchd);
#endif

  ServiceProcessState* state(new ServiceProcessState);
  bool service_process_state_initialized = state->Initialize();
  EXPECT_TRUE(service_process_state_initialized);
  if (!service_process_state_initialized)
    return kInitializationFailure;

  TestServiceProcess service_process;
  EXPECT_EQ(&service_process, g_service_process);

  // Takes ownership of the pointer, but we can use it since we have the same
  // lifetime.
  EXPECT_TRUE(service_process.Initialize(run_loop.QuitClosure(),
                                         base::WrapUnique(state)));

  // Needed for IPC.
  mojo::core::Init();
  mojo::core::ScopedIPCSupport ipc_support(
      service_process.io_task_runner(),
      mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST);

  MockServiceIPCServer server(&service_process,
                              service_process.io_task_runner(),
                              service_process.GetShutdownEventForTesting());
  server.binder_registry().AddInterface(base::Bind(
      &cloud_print::CloudPrintMessageHandler::Create, &service_process));

  // Here is where the expectations/mock responses need to be set up.
  set_expectations.Run(&server);

  EXPECT_TRUE(server.Init());
  EXPECT_TRUE(state->SignalReady(service_process.io_task_runner().get(),
                                 base::Bind(&ShutdownTask)));
#if defined(OS_MACOSX)
  mock_launchd.SignalReady();
#endif

  // Connect up the parent/child IPC channel to signal that the test can
  // continue.
  TestStartupClientChannelListener listener;
  EXPECT_TRUE(base::CommandLine::ForCurrentProcess()->HasSwitch(
      kProcessChannelID));
  auto server_name = mojo::NamedPlatformChannel::ServerNameFromUTF8(
      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
          kProcessChannelID));
  mojo::IsolatedConnection mojo_connection;
  std::unique_ptr<IPC::ChannelProxy> startup_channel =
      IPC::ChannelProxy::Create(
          mojo_connection
              .Connect(mojo::NamedPlatformChannel::ConnectToServer(server_name))
              .release(),
          IPC::Channel::MODE_CLIENT, &listener,
          service_process.io_task_runner(),
          base::ThreadTaskRunnerHandle::Get());

  run_loop.Run();
  if (!Mock::VerifyAndClearExpectations(&server))
    return kExpectationsNotMet;
  if (!g_good_shutdown)
    return kShutdownNotGood;
  return 0;
}

void SetServiceEnabledExpectations(MockServiceIPCServer* server) {
  server->SetServiceEnabledExpectations();
}

MULTIPROCESS_TEST_MAIN(CloudPrintMockService_StartEnabledWaitForQuit) {
  return CloudPrintMockService_Main(
      base::Bind(&SetServiceEnabledExpectations));
}

class CloudPrintProxyPolicyStartupTest : public base::MultiProcessTest,
                                         public IPC::Listener {
 public:
  CloudPrintProxyPolicyStartupTest();
  ~CloudPrintProxyPolicyStartupTest() override;

  void SetUp() override;
  void TearDown() override;

  scoped_refptr<base::SingleThreadTaskRunner> IOTaskRunner() {
    return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
  }
  base::Process Launch(const std::string& name);
  void WaitForConnect(mojo::IsolatedConnection* mojo_connection);
  void ShutdownAndWaitForExitWithTimeout(base::Process process);

  // IPC::Listener implementation
  bool OnMessageReceived(const IPC::Message& message) override { return false; }
  void OnChannelConnected(int32_t peer_pid) override;

  // MultiProcessTest implementation.
  base::CommandLine MakeCmdLine(const std::string& procname) override;

  bool LaunchBrowser(const base::CommandLine& command_line, Profile* profile) {
    StartupBrowserCreator browser_creator;
    return browser_creator.ProcessCmdLineImpl(
        command_line, base::FilePath(), false, profile,
        StartupBrowserCreator::Profiles());
  }

 protected:
  content::TestBrowserThreadBundle thread_bundle_;
  base::ScopedTempDir temp_user_data_dir_;

  mojo::NamedPlatformChannel::ServerName startup_server_name_;
  mojo::IsolatedConnection mojo_connection_;
  std::unique_ptr<IPC::ChannelProxy> startup_channel_;
  std::unique_ptr<ChromeContentClient> content_client_;
  std::unique_ptr<ChromeContentBrowserClient> browser_content_client_;

#if defined(OS_MACOSX)
  base::ScopedTempDir temp_dir_;
  base::FilePath executable_path_, bundle_path_;
  std::unique_ptr<MockLaunchd> mock_launchd_;
  std::unique_ptr<Launchd::ScopedInstance> scoped_launchd_instance_;
#endif

 private:
  class WindowedChannelConnectionObserver {
   public:
    WindowedChannelConnectionObserver()
        : seen_(false),
          running_(false) { }

    void Wait() {
      if (seen_)
        return;
      running_ = true;
      content::RunMessageLoop();
    }

    void Notify() {
      seen_ = true;
      if (running_)
        base::RunLoop::QuitCurrentWhenIdleDeprecated();
    }

   private:
    bool seen_;
    bool running_;
  };

  WindowedChannelConnectionObserver observer_;
};

CloudPrintProxyPolicyStartupTest::CloudPrintProxyPolicyStartupTest()
    : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD) {
  // Although is really a unit test which runs in the browser_tests binary, it
  // doesn't get the unit setup which normally happens in the unit test binary.
  ChromeUnitTestSuite::InitializeProviders();
  ChromeUnitTestSuite::InitializeResourceBundle();
}

CloudPrintProxyPolicyStartupTest::~CloudPrintProxyPolicyStartupTest() {
}

void CloudPrintProxyPolicyStartupTest::SetUp() {
  content_client_.reset(new ChromeContentClient);
  content::SetContentClient(content_client_.get());
  browser_content_client_.reset(new ChromeContentBrowserClient());
  content::SetBrowserClientForTesting(browser_content_client_.get());

  TestingBrowserProcess::CreateInstance();
  // Ensure test does not use the standard profile directory. This is copied
  // from InProcessBrowserTest::SetUp(). These tests require a more complex
  // process startup so they are unable to just inherit from
  // InProcessBrowserTest.
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  base::FilePath user_data_dir =
      command_line->GetSwitchValuePath(switches::kUserDataDir);
  if (user_data_dir.empty()) {
    ASSERT_TRUE(temp_user_data_dir_.CreateUniqueTempDir() &&
                temp_user_data_dir_.IsValid())
        << "Could not create temporary user data directory \""
        << temp_user_data_dir_.GetPath().value() << "\".";

    user_data_dir = temp_user_data_dir_.GetPath();
    command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir);
  }
  ASSERT_TRUE(test_launcher_utils::OverrideUserDataDir(user_data_dir));

#if defined(OS_MACOSX)
  EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
  EXPECT_TRUE(MockLaunchd::MakeABundle(temp_dir_.GetPath(),
                                       "CloudPrintProxyTest", &bundle_path_,
                                       &executable_path_));
  mock_launchd_.reset(new MockLaunchd(executable_path_,
                                      base::ThreadTaskRunnerHandle::Get(),
                                      base::DoNothing(), true, false));
  scoped_launchd_instance_.reset(
      new Launchd::ScopedInstance(mock_launchd_.get()));
#endif
}

void CloudPrintProxyPolicyStartupTest::TearDown() {
  browser_content_client_.reset();
  content_client_.reset();
  content::SetContentClient(NULL);

  TestingBrowserProcess::DeleteInstance();
}

base::Process CloudPrintProxyPolicyStartupTest::Launch(
    const std::string& name) {
  EXPECT_FALSE(CheckServiceProcessReady());

  startup_server_name_ = mojo::NamedPlatformChannel::ServerNameFromUTF8(
      base::StringPrintf("%" CrPRIdPid ".%p.%d", base::GetCurrentProcId(), this,
                         base::RandInt(0, std::numeric_limits<int>::max())));

  mojo::NamedPlatformChannel::Options options;
  options.server_name = startup_server_name_;
  mojo::NamedPlatformChannel channel_server(options);
  startup_channel_ = IPC::ChannelProxy::Create(
      mojo_connection_.Connect(channel_server.TakeServerEndpoint()).release(),
      IPC::Channel::MODE_SERVER, this, IOTaskRunner(),
      base::ThreadTaskRunnerHandle::Get());

  base::Process process = SpawnChild(name);
  EXPECT_TRUE(process.IsValid());
  return process;
}

void CloudPrintProxyPolicyStartupTest::WaitForConnect(
    mojo::IsolatedConnection* mojo_connection) {
  observer_.Wait();
  EXPECT_TRUE(CheckServiceProcessReady());
  EXPECT_TRUE(base::ThreadTaskRunnerHandle::Get().get());

  mojo::MessagePipe pipe;
  base::PostTaskWithTraits(
      FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
      base::BindOnce(&ConnectAsync, std::move(pipe.handle1),
                     GetServiceProcessServerName(), mojo_connection));
  ServiceProcessControl::GetInstance()->SetMojoHandle(
      mojo::MakeProxy(service_manager::mojom::InterfaceProviderPtrInfo(
          std::move(pipe.handle0), 0U)));
}

void CloudPrintProxyPolicyStartupTest::ShutdownAndWaitForExitWithTimeout(
    base::Process process) {
  chrome::mojom::ServiceProcessPtr service_process;
  ServiceProcessControl::GetInstance()->remote_interfaces().GetInterface(
      &service_process);
  service_process->ShutDown();

  int exit_code = -100;
  bool exited = process.WaitForExitWithTimeout(TestTimeouts::action_timeout(),
                                               &exit_code);
  EXPECT_TRUE(exited);
  EXPECT_EQ(0, exit_code);
}

void CloudPrintProxyPolicyStartupTest::OnChannelConnected(int32_t peer_pid) {
  observer_.Notify();
}

base::CommandLine CloudPrintProxyPolicyStartupTest::MakeCmdLine(
    const std::string& procname) {
  base::CommandLine cl = MultiProcessTest::MakeCmdLine(procname);
  cl.AppendSwitchNative(kProcessChannelID, startup_server_name_);
#if defined(OS_MACOSX)
  cl.AppendSwitchASCII(kTestExecutablePath, executable_path_.value());
#endif
  return cl;
}

TEST_F(CloudPrintProxyPolicyStartupTest, StartAndShutdown) {
  mojo::core::Init();
  mojo::core::ScopedIPCSupport ipc_support(
      BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
      mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST);

  base::Process process =
      Launch("CloudPrintMockService_StartEnabledWaitForQuit");
  mojo::IsolatedConnection mojo_connection;
  WaitForConnect(&mojo_connection);
  ShutdownAndWaitForExitWithTimeout(std::move(process));
  ServiceProcessControl::GetInstance()->Disconnect();
  content::RunAllPendingInMessageLoop();
}
