// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/updater/update_service_impl.h"

#include <string>
#include <utility>
#include <vector>

#include "base/functional/callback.h"
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h"
#include "chrome/updater/activity.h"
#include "chrome/updater/configurator.h"
#include "chrome/updater/constants.h"
#include "chrome/updater/persisted_data.h"
#include "chrome/updater/remove_uninstalled_apps_task.h"
#include "chrome/updater/update_service.h"
#include "chrome/updater/update_service_impl_impl.h"
#include "chrome/updater/util/util.h"

#if BUILDFLAG(IS_WIN)
#include "chrome/updater/util/win_util.h"
#endif

namespace updater {

UpdateServiceImpl::UpdateServiceImpl(UpdaterScope scope,
                                     scoped_refptr<Configurator> config)
    : scope_(scope),
      config_(config),
      delegate_(base::MakeRefCounted<UpdateServiceImplImpl>(config)) {}

void UpdateServiceImpl::GetVersion(
    base::OnceCallback<void(const base::Version&)> callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  delegate_->GetVersion(std::move(callback));
}

void UpdateServiceImpl::FetchPolicies(base::OnceCallback<void(int)> callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  delegate_->FetchPolicies(std::move(callback));
}

void UpdateServiceImpl::RegisterApp(const RegistrationRequest& request,
                                    base::OnceCallback<void(int)> callback) {
  // Registering apps with the updater is always allowed.
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  delegate_->RegisterApp(request, std::move(callback));
}

void UpdateServiceImpl::GetAppStates(
    base::OnceCallback<void(const std::vector<AppState>&)> callback) {
  // Asking the updater for app status is always allowed.
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  delegate_->GetAppStates(std::move(callback));
}

void UpdateServiceImpl::RunPeriodicTasks(base::OnceClosure callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!IsEulaAccepted() || IsOemMode()) {
    VLOG(1) << __func__ << " rejected (EULA required or OEM mode).";
    base::MakeRefCounted<RemoveUninstalledAppsTask>(config_, scope_)
        ->Run(std::move(callback));
    return;
  }
  delegate_->RunPeriodicTasks(std::move(callback));
}

void UpdateServiceImpl::CheckForUpdate(
    const std::string& app_id,
    Priority priority,
    PolicySameVersionUpdate policy_same_version_update,
    StateChangeCallback state_update,
    Callback callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!IsEulaAccepted() || IsOemMode()) {
    VLOG(1) << __func__ << " rejected (EULA required or OEM mode).";
    std::move(callback).Run(Result::kEulaRequiredOrOemMode);
    return;
  }
  delegate_->CheckForUpdate(app_id, priority, policy_same_version_update,
                            state_update, std::move(callback));
}

void UpdateServiceImpl::Update(
    const std::string& app_id,
    const std::string& install_data_index,
    Priority priority,
    PolicySameVersionUpdate policy_same_version_update,
    StateChangeCallback state_update,
    Callback callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!IsEulaAccepted() || IsOemMode()) {
    VLOG(1) << __func__ << " rejected (EULA required or OEM mode).";
    std::move(callback).Run(Result::kEulaRequiredOrOemMode);
    return;
  }
  delegate_->Update(app_id, install_data_index, priority,
                    policy_same_version_update, state_update,
                    std::move(callback));
}

void UpdateServiceImpl::UpdateAll(StateChangeCallback state_update,
                                  Callback callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!IsEulaAccepted() || IsOemMode()) {
    VLOG(1) << __func__ << " rejected (EULA required or OEM mode).";
    std::move(callback).Run(Result::kEulaRequiredOrOemMode);
    return;
  }
  delegate_->UpdateAll(state_update, std::move(callback));
}

void UpdateServiceImpl::Install(const RegistrationRequest& registration,
                                const std::string& client_install_data,
                                const std::string& install_data_index,
                                Priority priority,
                                StateChangeCallback state_update,
                                Callback callback) {
  // Online installers can only be downloaded after ToS acceptance.
  AcceptEula();
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  delegate_->Install(registration, client_install_data, install_data_index,
                     priority, state_update, std::move(callback));
}

void UpdateServiceImpl::CancelInstalls(const std::string& app_id) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  delegate_->CancelInstalls(app_id);
}

void UpdateServiceImpl::RunInstaller(const std::string& app_id,
                                     const base::FilePath& installer_path,
                                     const std::string& install_args,
                                     const std::string& install_data,
                                     const std::string& install_settings,
                                     StateChangeCallback state_update,
                                     Callback callback) {
  // Offline installs are always permitted, to support OEM cases.
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  delegate_->RunInstaller(app_id, installer_path, install_args, install_data,
                          install_settings, state_update, std::move(callback));
}

void UpdateServiceImpl::AcceptEula() {
  base::MakeRefCounted<PersistedData>(scope_, config_->GetPrefService(),
                                      nullptr)
      ->SetEulaRequired(false);
}

bool UpdateServiceImpl::IsEulaAccepted() {
  scoped_refptr<PersistedData> persisted_data =
      base::MakeRefCounted<PersistedData>(scope_, config_->GetPrefService(),
                                          nullptr);
  if (!persisted_data->GetEulaRequired()) {
    return true;
  }
  if (EulaAccepted(persisted_data->GetAppIds())) {
    // Mark the acceptance for future queries.
    AcceptEula();
    return true;
  }
  return false;
}

bool UpdateServiceImpl::IsOemMode() {
#if BUILDFLAG(IS_WIN)
  return IsSystemInstall() && IsOemInstalling();
#else
  return false;
#endif
}

UpdateServiceImpl::~UpdateServiceImpl() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}

}  // namespace updater
