// Copyright (c) 2013 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 "chrome/browser/chrome_process_singleton.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

bool ServerCallback(int* callback_count,
                    const base::CommandLine& command_line,
                    const base::FilePath& current_directory) {
  ++(*callback_count);
  return true;
}

bool ClientCallback(const base::CommandLine& command_line,
                    const base::FilePath& current_directory) {
  ADD_FAILURE();
  return false;
}

}  // namespace

TEST(ChromeProcessSingletonTest, Basic) {
  base::ScopedTempDir profile_dir;
  ASSERT_TRUE(profile_dir.CreateUniqueTempDir());

  int callback_count = 0;

  ChromeProcessSingleton ps1(
      profile_dir.GetPath(),
      base::Bind(&ServerCallback, base::Unretained(&callback_count)));
  ps1.Unlock();

  ChromeProcessSingleton ps2(profile_dir.GetPath(),
                             base::Bind(&ClientCallback));
  ps2.Unlock();

  ProcessSingleton::NotifyResult result = ps1.NotifyOtherProcessOrCreate();

  ASSERT_EQ(ProcessSingleton::PROCESS_NONE, result);
  ASSERT_EQ(0, callback_count);

  result = ps2.NotifyOtherProcessOrCreate();
  ASSERT_EQ(ProcessSingleton::PROCESS_NOTIFIED, result);

  ASSERT_EQ(1, callback_count);
}

TEST(ChromeProcessSingletonTest, Lock) {
  base::ScopedTempDir profile_dir;
  ASSERT_TRUE(profile_dir.CreateUniqueTempDir());

  int callback_count = 0;

  ChromeProcessSingleton ps1(
      profile_dir.GetPath(),
      base::Bind(&ServerCallback, base::Unretained(&callback_count)));

  ChromeProcessSingleton ps2(profile_dir.GetPath(),
                             base::Bind(&ClientCallback));
  ps2.Unlock();

  ProcessSingleton::NotifyResult result = ps1.NotifyOtherProcessOrCreate();

  ASSERT_EQ(ProcessSingleton::PROCESS_NONE, result);
  ASSERT_EQ(0, callback_count);

  result = ps2.NotifyOtherProcessOrCreate();
  ASSERT_EQ(ProcessSingleton::PROCESS_NOTIFIED, result);

  ASSERT_EQ(0, callback_count);
  ps1.Unlock();
  ASSERT_EQ(1, callback_count);
}

#if defined(OS_WIN) && !defined(USE_AURA)
namespace {

void SetForegroundWindowHandler(bool* flag,
                                gfx::NativeWindow /* target_window */) {
  *flag = true;
}

}  // namespace

TEST(ChromeProcessSingletonTest, LockWithModalDialog) {
  base::ScopedTempDir profile_dir;
  ASSERT_TRUE(profile_dir.CreateUniqueTempDir());

  int callback_count = 0;
  bool called_set_foreground_window = false;

  ChromeProcessSingleton ps1(
      profile_dir.GetPath(),
      base::Bind(&ServerCallback, base::Unretained(&callback_count)),
      base::Bind(&SetForegroundWindowHandler,
                 base::Unretained(&called_set_foreground_window)));
  ps1.SetActiveModalDialog(::GetShellWindow());

  ChromeProcessSingleton ps2(profile_dir.GetPath(),
                             base::Bind(&ClientCallback));
  ps2.Unlock();

  ProcessSingleton::NotifyResult result = ps1.NotifyOtherProcessOrCreate();

  ASSERT_EQ(ProcessSingleton::PROCESS_NONE, result);
  ASSERT_EQ(0, callback_count);

  ASSERT_FALSE(called_set_foreground_window);
  result = ps2.NotifyOtherProcessOrCreate();
  ASSERT_EQ(ProcessSingleton::PROCESS_NOTIFIED, result);
  ASSERT_TRUE(called_set_foreground_window);

  ASSERT_EQ(0, callback_count);
  ps1.SetActiveModalDialog(NULL);
  ps1.Unlock();
  // The notification sent while a modal dialog was present was silently
  // dropped.
  ASSERT_EQ(0, callback_count);

  // But now that the active modal dialog is NULL notifications will be handled.
  result = ps2.NotifyOtherProcessOrCreate();
  ASSERT_EQ(ProcessSingleton::PROCESS_NOTIFIED, result);
  ASSERT_EQ(1, callback_count);
}
#endif  // defined(OS_WIN) && !defined(USE_AURA)
