// Copyright 2018 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/component_updater/fake_cros_component_manager.h"

#include <utility>

#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/threading/sequenced_task_runner_handle.h"

namespace component_updater {

FakeCrOSComponentManager::ComponentInfo::ComponentInfo(
    Error load_response,
    const base::FilePath& install_path,
    const base::FilePath& mount_path)
    : load_response(load_response),
      install_path(install_path),
      mount_path(mount_path) {
  // If component load fails, neither install nor mount path should be set.
  DCHECK(load_response == Error::NONE ||
         (install_path.empty() && mount_path.empty()));
  // Component should have install path set if it's expected to be loaded.
  DCHECK(load_response != Error::NONE || !install_path.empty());
}

FakeCrOSComponentManager::ComponentInfo::~ComponentInfo() = default;

FakeCrOSComponentManager::FakeCrOSComponentManager() = default;

FakeCrOSComponentManager::~FakeCrOSComponentManager() = default;

bool FakeCrOSComponentManager::FinishLoadRequest(
    const std::string& name,
    const ComponentInfo& component_info) {
  if (!pending_loads_.count(name) || pending_loads_[name].empty()) {
    LOG(ERROR) << "No pending load for " << name;
    return false;
  }

  auto& pending_load = pending_loads_[name].front();
  FinishComponentLoad(name, pending_load.mount_requested, component_info);

  LoadCallback callback = std::move(pending_load.callback);
  pending_loads_[name].pop_front();

  std::move(callback).Run(component_info.load_response,
                          component_info.load_response == Error::NONE
                              ? component_info.mount_path
                              : base::FilePath());
  return true;
}

bool FakeCrOSComponentManager::ResetComponentState(const std::string& name,
                                                   const ComponentInfo& state) {
  if (!supported_components_.count(name))
    return false;

  installed_components_.erase(name);
  mounted_components_.erase(name);

  component_infos_.erase(name);
  component_infos_.emplace(
      name,
      ComponentInfo(state.load_response, state.install_path, state.mount_path));
  return true;
}

bool FakeCrOSComponentManager::HasPendingInstall(
    const std::string& name) const {
  DCHECK(queue_load_requests_);

  const auto& it = pending_loads_.find(name);
  return it != pending_loads_.end() && !it->second.empty();
}

bool FakeCrOSComponentManager::UpdateRequested(const std::string& name) const {
  DCHECK(queue_load_requests_);

  const auto& it = pending_loads_.find(name);
  return it != pending_loads_.end() && !it->second.empty() &&
         it->second.front().needs_update;
}

void FakeCrOSComponentManager::SetDelegate(Delegate* delegate) {
  // No-op, not used by the fake.
}

void FakeCrOSComponentManager::Load(const std::string& name,
                                    MountPolicy mount_policy,
                                    UpdatePolicy update_policy,
                                    LoadCallback load_callback) {
  if (!supported_components_.count(name)) {
    base::SequencedTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::BindOnce(std::move(load_callback),
                                  Error::UNKNOWN_COMPONENT, base::FilePath()));
    return;
  }

  bool needs_update = update_policy == UpdatePolicy::kForce ||
                      (!installed_components_.count(name) &&
                       update_policy != UpdatePolicy::kSkip);

  // The request has to be handled if the component is not yet installed, or it
  // requires immediate update.
  if (needs_update || !installed_components_.count(name)) {
    HandlePendingRequest(name, mount_policy == MountPolicy::kMount,
                         needs_update, std::move(load_callback));
    return;
  }

  // Handle request if the component has yet to be mounted - e.g. if previous
  // loads installed the component without mounting it.
  if (!mounted_components_.count(name) && mount_policy == MountPolicy::kMount) {
    HandlePendingRequest(name, true /*mount_requested*/, false /*needs_update*/,
                         std::move(load_callback));
    return;
  }

  // The component has been prevoiusly installed, and mounted as required by
  // this load request - run the callback according to the existing state.
  base::SequencedTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(std::move(load_callback), Error::NONE,
                                mount_policy == MountPolicy::kMount
                                    ? mounted_components_[name]
                                    : base::FilePath()));
}

bool FakeCrOSComponentManager::Unload(const std::string& name) {
  {
    base::AutoLock lock(registered_components_lock_);
    registered_components_.erase(name);
  }
  mounted_components_.erase(name);
  installed_components_.erase(name);
  return unload_component_result_;
}

void FakeCrOSComponentManager::RegisterCompatiblePath(
    const std::string& name,
    const base::FilePath& path) {
  installed_components_[name] = path;
}

void FakeCrOSComponentManager::UnregisterCompatiblePath(
    const std::string& name) {
  installed_components_.erase(name);
}

base::FilePath FakeCrOSComponentManager::GetCompatiblePath(
    const std::string& name) const {
  const auto& it = installed_components_.find(name);
  if (it == installed_components_.end())
    return base::FilePath();
  return it->second;
}

void FakeCrOSComponentManager::SetRegisteredComponents(
    const std::set<std::string>& components) {
  base::AutoLock lock(registered_components_lock_);
  registered_components_ = components;
}

bool FakeCrOSComponentManager::IsRegisteredMayBlock(const std::string& name) {
  base::AutoLock lock(registered_components_lock_);
  return registered_components_.count(name);
}

void FakeCrOSComponentManager::RegisterInstalled() {
  NOTIMPLEMENTED();
}

FakeCrOSComponentManager::LoadRequest::LoadRequest(bool mount_requested,
                                                   bool needs_update,
                                                   LoadCallback callback)
    : mount_requested(mount_requested),
      needs_update(needs_update),
      callback(std::move(callback)) {}

FakeCrOSComponentManager::LoadRequest::~LoadRequest() = default;

void FakeCrOSComponentManager::HandlePendingRequest(const std::string& name,
                                                    bool mount_requested,
                                                    bool needs_update,
                                                    LoadCallback callback) {
  if (queue_load_requests_) {
    pending_loads_[name].emplace_back(mount_requested, needs_update,
                                      std::move(callback));
    return;
  }

  const auto& component_info = component_infos_.find(name);
  if (component_info == component_infos_.end()) {
    base::SequencedTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::BindOnce(std::move(callback), Error::INSTALL_FAILURE,
                                  base::FilePath()));
    return;
  }

  FinishComponentLoad(name, mount_requested, component_info->second);

  base::SequencedTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      base::BindOnce(std::move(callback), component_info->second.load_response,
                     component_info->second.mount_path));
}

void FakeCrOSComponentManager::FinishComponentLoad(
    const std::string& name,
    bool mount_requested,
    const ComponentInfo& component_info) {
  {
    base::AutoLock lock(registered_components_lock_);
    registered_components_.insert(name);
  }

  if (component_info.load_response != Error::NONE)
    return;

  DCHECK_EQ(mount_requested, !component_info.mount_path.empty());
  installed_components_[name] = component_info.install_path;
  if (mount_requested)
    mounted_components_[name] = component_info.mount_path;
}

}  // namespace component_updater
