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

#include "content/browser/installedapp/installed_app_provider_impl.h"

#include <algorithm>

#include "base/check_is_test.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/functional/concurrent_callbacks.h"
#include "base/task/task_traits.h"
#include "build/build_config.h"
#include "content/browser/browser_thread_impl.h"
#if !BUILDFLAG(IS_ANDROID)
#include "content/browser/installedapp/fetch_related_web_apps_task.h"
#endif  // !BUILDFLAG(IS_ANDROID)
#include "content/common/features.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/content_features.h"
#include "mojo/public/cpp/bindings/clone_traits.h"
#include "third_party/blink/public/mojom/installedapp/related_application.mojom.h"

#if BUILDFLAG(IS_WIN)
#include "content/browser/installedapp/fetch_related_win_apps_task.h"
#include "content/browser/installedapp/native_win_app_fetcher.h"
#include "content/browser/installedapp/native_win_app_fetcher_impl.h"
#endif

namespace content {

namespace {
constexpr int kMaxNumberOfQueriedApps = 10;

#if BUILDFLAG(IS_WIN)
std::unique_ptr<NativeWinAppFetcher> CreateNativeWinAppFetcher() {
  return std::make_unique<NativeWinAppFetcherImpl>();
}
#endif  // BUILDFLAG(IS_WIN)
}

InstalledAppProviderImpl::InstalledAppProviderImpl(
    RenderFrameHost& render_frame_host,
    mojo::PendingReceiver<blink::mojom::InstalledAppProvider> pending_receiver)
    : DocumentService(render_frame_host, std::move(pending_receiver)) {
#if BUILDFLAG(IS_WIN)
  native_win_app_fetcher_factory_ =
      base::BindRepeating(&CreateNativeWinAppFetcher);
#endif  // BUILDFLAG(IS_WIN)
}

InstalledAppProviderImpl::~InstalledAppProviderImpl() = default;

void InstalledAppProviderImpl::FilterInstalledApps(
    std::vector<blink::mojom::RelatedApplicationPtr> related_apps,
    const GURL& manifest_url,
    bool add_saved_related_applications,
    FilterInstalledAppsCallback callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!base::FeatureList::IsEnabled(features::kInstalledAppProvider)) {
    base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE,
        base::BindOnce(std::move(callback),
                       std::vector<blink::mojom::RelatedApplicationPtr>()));
    return;
  }

  // If we failed to retrieve the manifest, fall back to the saved
  // related_apps.
  if (add_saved_related_applications) {
    WebContents* web_contents =
        WebContents::FromRenderFrameHost(&render_frame_host());
    WebContentsDelegate* delegate = web_contents->GetDelegate();
    if (delegate) {
      std::vector<blink::mojom::RelatedApplicationPtr> saved_related_apps =
          delegate->GetSavedRelatedApplications(web_contents);
      related_apps.insert(related_apps.end(),
                          std::make_move_iterator(saved_related_apps.begin()),
                          std::make_move_iterator(saved_related_apps.end()));
    }
  }

  if (related_apps.size() > kMaxNumberOfQueriedApps) {
    related_apps.resize(kMaxNumberOfQueriedApps);
  }

  base::ConcurrentCallbacks<FetchRelatedAppsTaskResult> concurrent;

#if BUILDFLAG(IS_WIN)
  if (base::FeatureList::IsEnabled(features::kFilterInstalledAppsWinMatching)) {
    StartTask(std::make_unique<FetchRelatedWinAppsTask>(
                  native_win_app_fetcher_factory_.Run()),
              related_apps, concurrent.CreateCallback());
  }
#endif

#if !BUILDFLAG(IS_ANDROID)
  if (base::FeatureList::IsEnabled(
          features::kFilterInstalledAppsWebAppMatching)) {
    StartTask(std::make_unique<FetchRelatedWebAppsTask>(
                  render_frame_host().GetBrowserContext()),
              related_apps, concurrent.CreateCallback());
  }
#endif  // !BUILDFLAG(IS_ANDROID)

  std::move(concurrent)
      .Done(base::BindOnce(&InstalledAppProviderImpl::AggregateTaskResults,
                           weak_ptr_factory_.GetWeakPtr(),
                           std::move(callback)));
}

void InstalledAppProviderImpl::StartTask(
    std::unique_ptr<FetchRelatedAppsTask> task,
    std::vector<blink::mojom::RelatedApplicationPtr>& related_apps,
    FetchRelatedAppsTaskCallback callback) {
  auto* task_ptr = task.get();
  tasks_.insert({task_ptr, std::move(task)});
  auto erase_task_cb = base::BindOnce(&InstalledAppProviderImpl::EraseTask,
                                      weak_ptr_factory_.GetWeakPtr(), task_ptr);
  task_ptr->Start(render_frame_host().GetLastCommittedURL(),
                  mojo::Clone(related_apps),
                  std::move(callback).Then(std::move(erase_task_cb)));
}

void InstalledAppProviderImpl::EraseTask(FetchRelatedAppsTask* task) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  int num_removed = tasks_.erase(task);
  CHECK(num_removed != 0);
}

void InstalledAppProviderImpl::AggregateTaskResults(
    FilterInstalledAppsCallback callback,
    std::vector<FetchRelatedAppsTaskResult> task_result_list) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  std::vector<blink::mojom::RelatedApplicationPtr> matched_apps;

  for (FetchRelatedAppsTaskResult& result : task_result_list) {
    for (blink::mojom::RelatedApplicationPtr& app : result) {
      matched_apps.push_back(std::move(app));
    }
  }

  // |is_off_the_record| should be checked at the end to prevent clients from
  // using timing functions to test if the user is in private.
  bool is_off_the_record =
      render_frame_host().GetProcess()->GetBrowserContext()->IsOffTheRecord();

  if (is_off_the_record) {
    return std::move(callback).Run(
        std::vector<blink::mojom::RelatedApplicationPtr>());
  }

  return std::move(callback).Run(mojo::Clone(matched_apps));
}

#if BUILDFLAG(IS_WIN)
void InstalledAppProviderImpl::SetNativeWinAppFetcherFactoryForTesting(
    base::RepeatingCallback<std::unique_ptr<NativeWinAppFetcher>()> factory) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  CHECK_IS_TEST();
  native_win_app_fetcher_factory_ = std::move(factory);
}
#endif  // BUILDFLAG(IS_WIN)

// static
void InstalledAppProviderImpl::Create(
    RenderFrameHost& host,
    mojo::PendingReceiver<blink::mojom::InstalledAppProvider> receiver) {
  if (host.GetParentOrOuterDocument()) {
    // The renderer is supposed to disallow this and we shouldn't end up here.
    mojo::ReportBadMessage(
        "InstalledAppProvider only allowed for outermost main frame.");
    return;
  }

  // The object is bound to the lifetime of |host|'s current document and the
  // mojo connection. See DocumentService for details.
  new InstalledAppProviderImpl(host, std::move(receiver));
}

// static
InstalledAppProviderImpl* InstalledAppProviderImpl::CreateForTesting(
    RenderFrameHost& render_frame_host,
    mojo::PendingReceiver<blink::mojom::InstalledAppProvider> receiver) {
  CHECK_IS_TEST();
  return new InstalledAppProviderImpl(render_frame_host, std::move(receiver));
}

}  // namespace content
