// Copyright 2016 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/installer/setup/setup_singleton.h"

#include <functional>
#include <utility>

#include "base/check_op.h"
#include "base/files/file_path.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "chrome/installer/setup/installer_state.h"
#include "chrome/installer/util/installation_state.h"

namespace installer {

std::unique_ptr<SetupSingleton> SetupSingleton::Acquire(
    const base::CommandLine& command_line,
    const MasterPreferences& master_preferences,
    InstallationState* original_state,
    InstallerState* installer_state) {
  DCHECK(original_state);
  DCHECK(installer_state);

  const base::string16 sync_primitive_name_suffix(
      base::NumberToString16(std::hash<base::FilePath::StringType>()(
          installer_state->target_path().value())));

  base::win::ScopedHandle setup_mutex(::CreateMutex(
      nullptr, FALSE,
      (L"Global\\ChromeSetupMutex_" + sync_primitive_name_suffix).c_str()));
  if (!setup_mutex.IsValid()) {
    // UMA data indicates that this happens 0.03 % of the time.
    return nullptr;
  }

  base::win::ScopedHandle exit_event(::CreateEvent(
      nullptr, TRUE, FALSE,
      (L"Global\\ChromeSetupExitEvent_" + sync_primitive_name_suffix).c_str()));
  if (!exit_event.IsValid()) {
    // UMA data indicates that this happens < 0.01 % of the time.
    return nullptr;
  }

  auto setup_singleton = base::WrapUnique(
      new SetupSingleton(std::move(setup_mutex), std::move(exit_event)));

  {
    // Acquire a mutex to ensure that a single call to SetupSingleton::Acquire()
    // signals |exit_event_| and waits for |setup_mutex_| to be released at a
    // time.
    base::win::ScopedHandle exit_event_mutex(::CreateMutex(
        nullptr, FALSE,
        (L"Global\\ChromeSetupExitEventMutex_" + sync_primitive_name_suffix)
            .c_str()));
    if (!exit_event_mutex.IsValid()) {
      // UMA data indicates that this happens < 0.01 % of the time.
      return nullptr;
    }

    ScopedHoldMutex scoped_hold_exit_event_mutex;
    if (!scoped_hold_exit_event_mutex.Acquire(exit_event_mutex.Get())) {
      // UMA data indicates that this happens < 0.01 % of the time.
      return nullptr;
    }

    // Signal |exit_event_|. This causes any call to WaitForInterrupt() on a
    // SetupSingleton bound to the same Chrome installation to return
    // immediately.
    setup_singleton->exit_event_.Signal();

    // Acquire |setup_mutex_|.
    if (!setup_singleton->scoped_hold_setup_mutex_.Acquire(
            setup_singleton->setup_mutex_.Get())) {
      // UMA data indicates that this happens 0.84 % of the time.
      return nullptr;
    }
    setup_singleton->exit_event_.Reset();
  }

  // Update |original_state| and |installer_state|.
  original_state->Initialize();
  installer_state->Initialize(command_line, master_preferences,
                              *original_state);

  // UMA data indicates that this method succeeds > 99% of the time.
  return setup_singleton;
}

SetupSingleton::~SetupSingleton() = default;

bool SetupSingleton::WaitForInterrupt(const base::TimeDelta& max_time) const {
  const bool exit_event_signaled = exit_event_.TimedWait(max_time);
  return exit_event_signaled;
}

SetupSingleton::ScopedHoldMutex::ScopedHoldMutex() = default;

SetupSingleton::ScopedHoldMutex::~ScopedHoldMutex() {
  if (mutex_ != INVALID_HANDLE_VALUE)
    ::ReleaseMutex(mutex_);
}

bool SetupSingleton::ScopedHoldMutex::Acquire(HANDLE mutex) {
  DCHECK_NE(INVALID_HANDLE_VALUE, mutex);
  DCHECK_EQ(INVALID_HANDLE_VALUE, mutex_);

  const DWORD wait_return_value = ::WaitForSingleObject(
      mutex,
      static_cast<DWORD>(base::TimeDelta::FromSeconds(5).InMilliseconds()));
  if (wait_return_value == WAIT_ABANDONED ||
      wait_return_value == WAIT_OBJECT_0) {
    mutex_ = mutex;
    return true;
  }

  DPCHECK(wait_return_value != WAIT_FAILED);
  return false;
}

SetupSingleton::SetupSingleton(base::win::ScopedHandle setup_mutex,
                               base::win::ScopedHandle exit_event)
    : setup_mutex_(std::move(setup_mutex)), exit_event_(std::move(exit_event)) {
  DCHECK(setup_mutex_.IsValid());
}

}  // namespace installer
