// Copyright (c) 2014 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 "components/browser_watcher/watcher_client_win.h"

#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>

#include <string>

#include "base/base_switches.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/process/kill.h"
#include "base/process/process.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/multiprocess_test.h"
#include "base/test/test_reg_util_win.h"
#include "base/win/scoped_handle.h"
#include "components/browser_watcher/exit_code_watcher_win.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"

namespace browser_watcher {

namespace {

// Command line switch used to communiate to the child test.
const char kParentHandle[] = "parent-handle";

bool IsValidParentProcessHandle(base::CommandLine& cmd_line,
                                const char* switch_name) {
  std::string str_handle =
      cmd_line.GetSwitchValueASCII(switch_name);

  size_t integer_handle = 0;
  if (!base::StringToSizeT(str_handle, &integer_handle))
    return false;

  base::ProcessHandle handle =
      reinterpret_cast<base::ProcessHandle>(integer_handle);
  // Verify that we can get the associated process id.
  base::ProcessId parent_id = base::GetProcId(handle);
  if (parent_id == 0) {
    // Unable to get the parent pid - perhaps insufficient permissions.
    return false;
  }

  // Make sure the handle grants SYNCHRONIZE by waiting on it.
  DWORD err = ::WaitForSingleObject(handle, 0);
  if (err != WAIT_OBJECT_0 && err != WAIT_TIMEOUT) {
    // Unable to wait on the handle - perhaps insufficient permissions.
    return false;
  }

  return true;
}

std::string HandleToString(HANDLE handle) {
  // A HANDLE is a void* pointer, which is the same size as a size_t,
  // so we can use reinterpret_cast<> on it.
  size_t integer_handle = reinterpret_cast<size_t>(handle);
  return base::SizeTToString(integer_handle);
}

MULTIPROCESS_TEST_MAIN(VerifyParentHandle) {
  base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();

  // Make sure we got a valid parent process handle from the watcher client.
  if (!IsValidParentProcessHandle(*cmd_line, kParentHandle)) {
    LOG(ERROR) << "Invalid or missing parent-handle.";
    return 1;
  }

  return 0;
}

class WatcherClientTest : public base::MultiProcessTest {
 public:
  void SetUp() override {
    // Open an inheritable handle on our own process to test handle leakage.
    self_.Set(::OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION,
                            TRUE,  // Ineritable handle.
                            base::GetCurrentProcId()));

    ASSERT_TRUE(self_.IsValid());
  }

  // Get a base command line to launch back into this test fixture.
  base::CommandLine GetBaseCommandLine(HANDLE parent_handle) {
    base::CommandLine ret = base::GetMultiProcessTestChildBaseCommandLine();

    ret.AppendSwitchASCII(switches::kTestChildProcess, "VerifyParentHandle");
    ret.AppendSwitchASCII(kParentHandle, HandleToString(parent_handle));

    return ret;
  }

  WatcherClient::CommandLineGenerator GetBaseCommandLineGenerator() {
    return base::Bind(&WatcherClientTest::GetBaseCommandLine,
                      base::Unretained(this));
  }

  void AssertSuccessfulExitCode(base::Process process) {
    ASSERT_TRUE(process.IsValid());
    int exit_code = 0;
    if (!process.WaitForExit(&exit_code))
      FAIL() << "Process::WaitForExit failed.";
    ASSERT_EQ(0, exit_code);
  }

  // Inheritable process handle used for testing.
  base::win::ScopedHandle self_;
};

}  // namespace

// TODO(siggi): More testing - test WatcherClient base implementation.

TEST_F(WatcherClientTest, LaunchWatcherSucceeds) {
  WatcherClient client(GetBaseCommandLineGenerator());

  client.LaunchWatcher();

  ASSERT_NO_FATAL_FAILURE(
      AssertSuccessfulExitCode(client.process().Duplicate()));
}

}  // namespace browser_watcher
