// Copyright 2017 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/extensions/bookmark_app_navigation_throttle.h"

#include <memory>

#include "base/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/extensions/launch_util.h"
#include "chrome/browser/prerender/prerender_contents.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/extensions/app_launch_params.h"
#include "chrome/browser/ui/extensions/application_launch.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/common/extensions/api/url_handlers/url_handlers_parser.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "ui/base/page_transition_types.h"
#include "ui/base/window_open_disposition.h"
#include "url/gurl.h"

using content::BrowserThread;

namespace extensions {

using ProcessNavigationResult =
    BookmarkAppNavigationThrottle::ProcessNavigationResult;

namespace {

// Non-app site navigations: The majority of navigations will be in-browser to
// sites for which there is no app installed. These navigations offer no insight
// so we avoid recording their outcome.

void RecordProcessNavigationResult(ProcessNavigationResult result) {
  UMA_HISTOGRAM_ENUMERATION("Extensions.BookmarkApp.NavigationResult", result,
                            ProcessNavigationResult::kCount);
}

void RecordProceedWithTransitionType(ui::PageTransition transition_type) {
  if (PageTransitionCoreTypeIs(transition_type, ui::PAGE_TRANSITION_LINK)) {
    // Link navigations are a special case and shouldn't use this code path.
    NOTREACHED();
  } else if (PageTransitionCoreTypeIs(transition_type,
                                      ui::PAGE_TRANSITION_TYPED)) {
    RecordProcessNavigationResult(
        ProcessNavigationResult::kProceedTransitionTyped);
  } else if (PageTransitionCoreTypeIs(transition_type,
                                      ui::PAGE_TRANSITION_AUTO_BOOKMARK)) {
    RecordProcessNavigationResult(
        ProcessNavigationResult::kProceedTransitionAutoBookmark);
  } else if (PageTransitionCoreTypeIs(transition_type,
                                      ui::PAGE_TRANSITION_AUTO_SUBFRAME)) {
    RecordProcessNavigationResult(
        ProcessNavigationResult::kProceedTransitionAutoSubframe);
  } else if (PageTransitionCoreTypeIs(transition_type,
                                      ui::PAGE_TRANSITION_MANUAL_SUBFRAME)) {
    RecordProcessNavigationResult(
        ProcessNavigationResult::kProceedTransitionManualSubframe);
  } else if (PageTransitionCoreTypeIs(transition_type,
                                      ui::PAGE_TRANSITION_GENERATED)) {
    RecordProcessNavigationResult(
        ProcessNavigationResult::kProceedTransitionGenerated);
  } else if (PageTransitionCoreTypeIs(transition_type,
                                      ui::PAGE_TRANSITION_AUTO_TOPLEVEL)) {
    RecordProcessNavigationResult(
        ProcessNavigationResult::kProceedTransitionAutoToplevel);
  } else if (PageTransitionCoreTypeIs(transition_type,
                                      ui::PAGE_TRANSITION_FORM_SUBMIT)) {
    // Form navigations are a special case and shouldn't use this code path.
    // TODO(crbug.com/772803): Add NOTREACHED() once form navigations are
    // handled.
  } else if (PageTransitionCoreTypeIs(transition_type,
                                      ui::PAGE_TRANSITION_RELOAD)) {
    RecordProcessNavigationResult(
        ProcessNavigationResult::kProceedTransitionReload);
  } else if (PageTransitionCoreTypeIs(transition_type,
                                      ui::PAGE_TRANSITION_KEYWORD)) {
    RecordProcessNavigationResult(
        ProcessNavigationResult::kProceedTransitionKeyword);
  } else if (PageTransitionCoreTypeIs(transition_type,
                                      ui::PAGE_TRANSITION_KEYWORD_GENERATED)) {
    RecordProcessNavigationResult(
        ProcessNavigationResult::kProceedTransitionKeywordGenerated);
  } else {
    NOTREACHED();
  }
}

bool IsWindowedBookmarkApp(const Extension* app,
                           content::BrowserContext* context) {
  if (!app || !app->from_bookmark())
    return false;

  if (GetLaunchContainer(extensions::ExtensionPrefs::Get(context), app) !=
      LAUNCH_CONTAINER_WINDOW) {
    return false;
  }

  return true;
}

scoped_refptr<const Extension> GetAppForURL(
    const GURL& url,
    const content::WebContents* web_contents) {
  content::BrowserContext* context = web_contents->GetBrowserContext();
  for (scoped_refptr<const extensions::Extension> app :
       ExtensionRegistry::Get(context)->enabled_extensions()) {
    if (!IsWindowedBookmarkApp(app.get(), context))
      continue;

    const UrlHandlerInfo* url_handler =
        UrlHandlers::FindMatchingUrlHandler(app.get(), url);
    if (!url_handler)
      continue;

    return app;
  }

  return nullptr;
}

}  // namespace

// static
std::unique_ptr<content::NavigationThrottle>
BookmarkAppNavigationThrottle::MaybeCreateThrottleFor(
    content::NavigationHandle* navigation_handle) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  DVLOG(1) << "Considering URL for interception: "
           << navigation_handle->GetURL().spec();
  if (!navigation_handle->IsInMainFrame()) {
    DVLOG(1) << "Don't intercept: Navigation is not in main frame.";
    return nullptr;
  }

  content::BrowserContext* browser_context =
      navigation_handle->GetWebContents()->GetBrowserContext();
  Profile* profile = Profile::FromBrowserContext(browser_context);
  if (profile->GetProfileType() == Profile::INCOGNITO_PROFILE) {
    DVLOG(1) << "Don't intercept: Navigation is in incognito.";
    return nullptr;
  }

  DVLOG(1) << "Attaching Bookmark App Navigation Throttle.";
  return std::make_unique<extensions::BookmarkAppNavigationThrottle>(
      navigation_handle);
}

BookmarkAppNavigationThrottle::BookmarkAppNavigationThrottle(
    content::NavigationHandle* navigation_handle)
    : content::NavigationThrottle(navigation_handle), weak_ptr_factory_(this) {}

BookmarkAppNavigationThrottle::~BookmarkAppNavigationThrottle() {}

const char* BookmarkAppNavigationThrottle::GetNameForLogging() {
  return "BookmarkAppNavigationThrottle";
}

content::NavigationThrottle::ThrottleCheckResult
BookmarkAppNavigationThrottle::WillStartRequest() {
  return ProcessNavigation(false /* is_redirect */);
}

content::NavigationThrottle::ThrottleCheckResult
BookmarkAppNavigationThrottle::WillRedirectRequest() {
  return ProcessNavigation(true /* is_redirect */);
}

content::NavigationThrottle::ThrottleCheckResult
BookmarkAppNavigationThrottle::ProcessNavigation(bool is_redirect) {
  scoped_refptr<const Extension> target_app = GetTargetApp();

  if (navigation_handle()->WasStartedFromContextMenu()) {
    DVLOG(1) << "Don't intercept: Navigation started from the context menu.";

    // See "Non-app site navigations" note above.
    if (target_app) {
      RecordProcessNavigationResult(
          ProcessNavigationResult::kProceedStartedFromContextMenu);
    }

    return content::NavigationThrottle::PROCEED;
  }

  ui::PageTransition transition_type = navigation_handle()->GetPageTransition();

  // When launching an app, if the page redirects to an out-of-scope URL, then
  // continue the navigation in a regular browser window. (Launching an app
  // results in an AUTO_BOOKMARK transition).
  //
  // Note that for non-redirecting app launches, GetAppForWindow() might return
  // null, because the navigation's WebContents might not be attached to a
  // window yet.
  //
  // TODO(crbug.com/789051): Possibly fall through to the logic below to
  // open target in app window, if it belongs to an app.
  if (is_redirect && PageTransitionCoreTypeIs(
                         transition_type, ui::PAGE_TRANSITION_AUTO_BOOKMARK)) {
    auto app_for_window = GetAppForWindow();
    // If GetAppForWindow returned nullptr, we are already in the browser, so
    // don't open a new tab.
    if (app_for_window && app_for_window != GetTargetApp()) {
      DVLOG(1) << "Out-of-scope navigation during launch. Opening in Chrome.";
      RecordProcessNavigationResult(
          ProcessNavigationResult::kOpenInChromeProceedOutOfScopeLaunch);
      Browser* browser = chrome::FindBrowserWithWebContents(
          navigation_handle()->GetWebContents());
      DCHECK(browser);
      chrome::OpenInChrome(browser);
      return content::NavigationThrottle::PROCEED;
    }
  }

  if (!PageTransitionCoreTypeIs(transition_type, ui::PAGE_TRANSITION_LINK) &&
      !PageTransitionCoreTypeIs(transition_type,
                                ui::PAGE_TRANSITION_FORM_SUBMIT)) {
    DVLOG(1) << "Don't intercept: Transition type is "
             << PageTransitionGetCoreTransitionString(transition_type);
    // We are in one of three possible states:
    //   1. In-browser no-target-app navigations,
    //   2. In-browser same-scope navigations, or
    //   3. In-app same-scope navigations
    // Ignore (1) since that's the majority of navigations and offer no insight.
    if (target_app)
      RecordProceedWithTransitionType(transition_type);

    return content::NavigationThrottle::PROCEED;
  }

  int32_t transition_qualifier = PageTransitionGetQualifier(transition_type);
  if (transition_qualifier & ui::PAGE_TRANSITION_FORWARD_BACK) {
    DVLOG(1) << "Don't intercept: Forward or back navigation.";

    // See "Non-app site navigations" note above.
    if (target_app) {
      RecordProcessNavigationResult(
          ProcessNavigationResult::kProceedTransitionForwardBack);
    }
    return content::NavigationThrottle::PROCEED;
  }

  if (transition_qualifier & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR) {
    DVLOG(1) << "Don't intercept: Address bar navigation.";

    // See "Non-app site navigations" note above.
    if (target_app) {
      RecordProcessNavigationResult(
          ProcessNavigationResult::kProceedTransitionFromAddressBar);
    }
    return content::NavigationThrottle::PROCEED;
  }

  scoped_refptr<const Extension> app_for_window = GetAppForWindow();

  if (app_for_window == target_app) {
    if (app_for_window) {
      DVLOG(1) << "Don't intercept: The target URL is in the same scope as the "
               << "current app.";

      // We know we are navigating within the same app window (both
      // |app_for_window| and |target_app| are the same and non-null). This is
      // relevant, so record the result.
      RecordProcessNavigationResult(
          ProcessNavigationResult::kProceedInAppSameScope);
    } else {
      DVLOG(1) << "No matching Bookmark App for URL: "
               << navigation_handle()->GetURL();
      // See "Non-app site navigations" note above.
    }
    DVLOG(1) << "Don't intercept: The target URL is in the same scope as the "
             << "current app.";
    return content::NavigationThrottle::PROCEED;
  }

  // If this is a browser tab, and the user is submitting a form, then keep the
  // navigation in the browser tab.
  if (!app_for_window &&
      PageTransitionCoreTypeIs(transition_type,
                               ui::PAGE_TRANSITION_FORM_SUBMIT)) {
    DVLOG(1) << "Keep form submissions in the browser.";
    RecordProcessNavigationResult(
        ProcessNavigationResult::kProceedInBrowserFormSubmission);
    return content::NavigationThrottle::PROCEED;
  }

  // If this is a browser tab, and the current and target URL are within-scope
  // of the same app, don't intercept the navigation.
  // This ensures that navigating from
  // https://www.youtube.com/ to https://www.youtube.com/some_video doesn't
  // open a new app window if the Youtube app is installed, but navigating from
  // https://www.google.com/ to https://www.google.com/maps does open a new
  // app window if only the Maps app is installed.
  if (!app_for_window && target_app == GetAppForCurrentURL()) {
    DVLOG(1) << "Don't intercept: Keep same-app navigations in the browser.";
    RecordProcessNavigationResult(
        ProcessNavigationResult::kProceedInBrowserSameScope);
    return content::NavigationThrottle::PROCEED;
  }

  if (target_app) {
    auto* prerender_contents = prerender::PrerenderContents::FromWebContents(
        navigation_handle()->GetWebContents());
    if (prerender_contents) {
      // If prerendering, don't launch the app but abort the navigation.
      prerender_contents->Destroy(
          prerender::FINAL_STATUS_NAVIGATION_INTERCEPTED);
      RecordProcessNavigationResult(
          ProcessNavigationResult::kCancelPrerenderContents);
      return content::NavigationThrottle::CANCEL_AND_IGNORE;
    }

    content::NavigationEntry* last_entry = navigation_handle()
                                               ->GetWebContents()
                                               ->GetController()
                                               .GetLastCommittedEntry();
    // We are about to open a new app window context. Record the time since the
    // last navigation in this context. (If it is very small, this context
    // probably redirected immediately, which is a bad user experience.)
    if (last_entry && !last_entry->GetTimestamp().is_null()) {
      UMA_HISTOGRAM_MEDIUM_TIMES(
          "Extensions.BookmarkApp.TimeBetweenOpenAppAndLastNavigation",
          base::Time::Now() - last_entry->GetTimestamp());
    }

    content::NavigationThrottle::ThrottleCheckResult result =
        OpenInAppWindowAndCloseTabIfNecessary(target_app);

    ProcessNavigationResult open_in_app_result;
    switch (result.action()) {
      case content::NavigationThrottle::DEFER:
        open_in_app_result =
            ProcessNavigationResult::kDeferOpenAppCloseEmptyWebContents;
        break;
      case content::NavigationThrottle::CANCEL_AND_IGNORE:
        open_in_app_result = ProcessNavigationResult::kCancelOpenedApp;
        break;
      default:
        NOTREACHED();
        open_in_app_result =
            ProcessNavigationResult::kDeferOpenAppCloseEmptyWebContents;
    }

    RecordProcessNavigationResult(open_in_app_result);
    return result;
  }

  if (app_for_window) {
    // The experience when navigating to an out-of-scope website inside an app
    // window is not great, so we bounce these navigations back to the browser.
    // TODO(crbug.com/774895): Stop bouncing back to the browser once the
    // experience for out-of-scope navigations improves.
    DVLOG(1) << "Open in new tab.";
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::Bind(&BookmarkAppNavigationThrottle::OpenInNewTab,
                              weak_ptr_factory_.GetWeakPtr()));
    RecordProcessNavigationResult(
        ProcessNavigationResult::kDeferOpenNewTabInAppOutOfScope);
    return content::NavigationThrottle::DEFER;
  }

  DVLOG(1) << "No matching Bookmark App for URL: "
           << navigation_handle()->GetURL();
  return content::NavigationThrottle::PROCEED;
}

content::NavigationThrottle::ThrottleCheckResult
BookmarkAppNavigationThrottle::OpenInAppWindowAndCloseTabIfNecessary(
    scoped_refptr<const Extension> target_app) {
  content::WebContents* source = navigation_handle()->GetWebContents();
  if (source->GetController().IsInitialNavigation()) {
    // When a new WebContents has no opener, the first navigation will happen
    // synchronously. This could result in us opening the app and then focusing
    // the original WebContents. To avoid this we open the app asynchronously.
    if (!source->HasOpener()) {
      DVLOG(1) << "Deferring opening app.";
      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(&BookmarkAppNavigationThrottle::OpenBookmarkApp,
                                weak_ptr_factory_.GetWeakPtr(), target_app));
    } else {
      OpenBookmarkApp(target_app);
    }

    // According to NavigationThrottle::WillStartRequest's documentation closing
    // a WebContents should be done asynchronously to avoid UAFs. Closing the
    // WebContents will cancel the navigation.
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::Bind(&BookmarkAppNavigationThrottle::CloseWebContents,
                              weak_ptr_factory_.GetWeakPtr()));
    return content::NavigationThrottle::DEFER;
  }

  OpenBookmarkApp(target_app);
  return content::NavigationThrottle::CANCEL_AND_IGNORE;
}

void BookmarkAppNavigationThrottle::OpenBookmarkApp(
    scoped_refptr<const Extension> bookmark_app) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  content::WebContents* source = navigation_handle()->GetWebContents();
  content::BrowserContext* browser_context = source->GetBrowserContext();
  Profile* profile = Profile::FromBrowserContext(browser_context);
  AppLaunchParams launch_params(
      profile, bookmark_app.get(), extensions::LAUNCH_CONTAINER_WINDOW,
      WindowOpenDisposition::CURRENT_TAB, extensions::SOURCE_URL_HANDLER);
  launch_params.override_url = navigation_handle()->GetURL();

  DVLOG(1) << "Opening app.";
  OpenApplication(launch_params);
}

void BookmarkAppNavigationThrottle::CloseWebContents() {
  DVLOG(1) << "Closing empty tab.";
  navigation_handle()->GetWebContents()->Close();
}

void BookmarkAppNavigationThrottle::OpenInNewTab() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  content::WebContents* source = navigation_handle()->GetWebContents();
  content::OpenURLParams url_params(navigation_handle()->GetURL(),
                                    navigation_handle()->GetReferrer(),
                                    WindowOpenDisposition::NEW_FOREGROUND_TAB,
                                    navigation_handle()->GetPageTransition(),
                                    navigation_handle()->IsRendererInitiated());
  url_params.uses_post = navigation_handle()->IsPost();
  url_params.post_data = navigation_handle()->GetResourceRequestBody();
  url_params.redirect_chain = navigation_handle()->GetRedirectChain();
  url_params.frame_tree_node_id = navigation_handle()->GetFrameTreeNodeId();
  url_params.user_gesture = navigation_handle()->HasUserGesture();
  url_params.started_from_context_menu =
      navigation_handle()->WasStartedFromContextMenu();

  source->OpenURL(url_params);
  CancelDeferredNavigation(content::NavigationThrottle::CANCEL_AND_IGNORE);
}

scoped_refptr<const Extension>
BookmarkAppNavigationThrottle::GetAppForWindow() {
  SCOPED_UMA_HISTOGRAM_TIMER("Extensions.BookmarkApp.GetAppForWindowDuration");
  content::WebContents* source = navigation_handle()->GetWebContents();
  content::BrowserContext* context = source->GetBrowserContext();
  Browser* browser = chrome::FindBrowserWithWebContents(source);
  if (!browser || !browser->is_app())
    return nullptr;

  const Extension* app = ExtensionRegistry::Get(context)->GetExtensionById(
      web_app::GetExtensionIdFromApplicationName(browser->app_name()),
      extensions::ExtensionRegistry::ENABLED);

  if (!IsWindowedBookmarkApp(app, context))
    return nullptr;

  // Bookmark Apps for installable websites have scope.
  // TODO(crbug.com/774918): Replace once there is a more explicit indicator
  // of a Bookmark App for an installable website.
  if (UrlHandlers::GetUrlHandlers(app) == nullptr)
    return nullptr;

  return app;
}

scoped_refptr<const Extension> BookmarkAppNavigationThrottle::GetTargetApp() {
  SCOPED_UMA_HISTOGRAM_TIMER("Extensions.BookmarkApp.GetTargetAppDuration");
  return GetAppForURL(navigation_handle()->GetURL(),
                      navigation_handle()->GetWebContents());
}

scoped_refptr<const Extension>
BookmarkAppNavigationThrottle::GetAppForCurrentURL() {
  SCOPED_UMA_HISTOGRAM_TIMER(
      "Extensions.BookmarkApp.GetAppForCurrentURLDuration");
  return GetAppForURL(navigation_handle()
                          ->GetWebContents()
                          ->GetMainFrame()
                          ->GetLastCommittedURL(),
                      navigation_handle()->GetWebContents());
}

}  // namespace extensions
