// 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/banners/app_banner_ui_delegate_android.h"

#include <utility>

#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "chrome/browser/android/shortcut_helper.h"
#include "chrome/browser/android/shortcut_info.h"
#include "chrome/browser/android/tab_android.h"
#include "chrome/browser/android/webapk/webapk_install_service.h"
#include "chrome/browser/android/webapk/webapk_metrics.h"
#include "chrome/browser/banners/app_banner_manager.h"
#include "chrome/browser/banners/app_banner_metrics.h"
#include "chrome/browser/banners/app_banner_settings_helper.h"
#include "chrome/browser/browser_process.h"
#include "components/rappor/public/rappor_utils.h"
#include "components/rappor/rappor_service_impl.h"
#include "components/url_formatter/elide_url.h"
#include "content/public/browser/web_contents.h"
#include "jni/AppBannerUiDelegateAndroid_jni.h"
#include "ui/gfx/android/java_bitmap.h"
#include "url/gurl.h"

namespace banners {

// static
std::unique_ptr<AppBannerUiDelegateAndroid> AppBannerUiDelegateAndroid::Create(
    base::WeakPtr<AppBannerManager> weak_manager,
    std::unique_ptr<ShortcutInfo> shortcut_info,
    const SkBitmap& primary_icon,
    const SkBitmap& badge_icon,
    WebappInstallSource install_source,
    bool is_webapk) {
  return std::unique_ptr<AppBannerUiDelegateAndroid>(
      new AppBannerUiDelegateAndroid(weak_manager, std::move(shortcut_info),
                                     primary_icon, badge_icon, install_source,
                                     is_webapk));
}

// static
std::unique_ptr<AppBannerUiDelegateAndroid> AppBannerUiDelegateAndroid::Create(
    base::WeakPtr<AppBannerManager> weak_manager,
    const base::string16& app_title,
    const base::android::ScopedJavaLocalRef<jobject>& native_app_data,
    const SkBitmap& icon,
    const std::string& native_app_package_name) {
  return std::unique_ptr<AppBannerUiDelegateAndroid>(
      new AppBannerUiDelegateAndroid(weak_manager, app_title, native_app_data,
                                     icon, native_app_package_name));
}

AppBannerUiDelegateAndroid::~AppBannerUiDelegateAndroid() {
  if (!has_user_interaction_) {
    AppType type = GetType();
    if (type == AppType::NATIVE) {
      TrackUserResponse(USER_RESPONSE_NATIVE_APP_IGNORED);
    } else {
      TrackUserResponse(USER_RESPONSE_WEB_APP_IGNORED);
      if (type == AppType::WEBAPK)
        webapk::TrackInstallEvent(webapk::INFOBAR_IGNORED);
    }
  }

  TrackDismissEvent(DISMISS_EVENT_DISMISSED);
  Java_AppBannerUiDelegateAndroid_destroy(base::android::AttachCurrentThread(),
                                          java_delegate_);
  java_delegate_.Reset();
}

const base::string16& AppBannerUiDelegateAndroid::GetAppTitle() const {
  return app_title_;
}

base::android::ScopedJavaLocalRef<jobject>
AppBannerUiDelegateAndroid::GetJavaObject() {
  return base::android::ScopedJavaLocalRef<jobject>(java_delegate_);
}

const base::android::ScopedJavaLocalRef<jobject>
AppBannerUiDelegateAndroid::GetNativeAppData() const {
  return base::android::ScopedJavaLocalRef<jobject>(native_app_data_);
}

const SkBitmap& AppBannerUiDelegateAndroid::GetPrimaryIcon() const {
  return primary_icon_;
}

AppBannerUiDelegateAndroid::AppType AppBannerUiDelegateAndroid::GetType()
    const {
  return type_;
}

const GURL& AppBannerUiDelegateAndroid::GetWebAppUrl() const {
  return shortcut_info_->url;
}

void AppBannerUiDelegateAndroid::AddToHomescreen(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& obj) {
  if (!weak_manager_.get())
    return;

  InstallApp(weak_manager_->web_contents());
}

const base::android::ScopedJavaLocalRef<jobject>
AppBannerUiDelegateAndroid::GetAddToHomescreenDialogForTesting() const {
  return Java_AppBannerUiDelegateAndroid_getDialogForTesting(
      base::android::AttachCurrentThread(), java_delegate_);
}

bool AppBannerUiDelegateAndroid::InstallApp(
    content::WebContents* web_contents) {
  has_user_interaction_ = true;

  if (!web_contents) {
    TrackDismissEvent(DISMISS_EVENT_ERROR);
    return true;
  }

  bool should_close_banner = true;
  switch (GetType()) {
    case AppType::NATIVE:
      should_close_banner = InstallOrOpenNativeApp();
      break;
    case AppType::WEBAPK:
      InstallWebApk(web_contents);
      break;
    case AppType::LEGACY_WEBAPP:
      InstallLegacyWebApp(web_contents);
      break;
  }
  SendBannerAccepted();
  return should_close_banner;
}

void AppBannerUiDelegateAndroid::OnNativeAppInstallStarted(
    content::WebContents* web_contents) {
  AppBannerSettingsHelper::RecordBannerEvent(
      web_contents, web_contents->GetVisibleURL(), package_name_,
      AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN,
      AppBannerManager::GetCurrentTime());

  TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_STARTED);
  rappor::SampleDomainAndRegistryFromGURL(g_browser_process->rappor_service(),
                                          "AppBanner.NativeApp.Installed",
                                          web_contents->GetURL());
}

void AppBannerUiDelegateAndroid::OnNativeAppInstallFinished(bool success) {
  if (success)
    TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_COMPLETED);
  else
    TrackDismissEvent(DISMISS_EVENT_INSTALL_TIMEOUT);
}

void AppBannerUiDelegateAndroid::OnUiCancelled(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& obj) {
  OnUiCancelled();
}

void AppBannerUiDelegateAndroid::OnUiCancelled() {
  if (!weak_manager_.get())
    return;

  weak_manager_->SendBannerDismissed();
  has_user_interaction_ = true;
  content::WebContents* web_contents = weak_manager_->web_contents();

  if (IsForNativeApp()) {
    DCHECK(!package_name_.empty());
    TrackUserResponse(USER_RESPONSE_NATIVE_APP_DISMISSED);
    AppBannerSettingsHelper::RecordBannerDismissEvent(
        web_contents, package_name_, AppBannerSettingsHelper::NATIVE);
  } else {
    DCHECK(GetType() == AppType::WEBAPK || GetType() == AppType::LEGACY_WEBAPP);

    if (GetType() == AppType::WEBAPK)
      webapk::TrackInstallEvent(webapk::INFOBAR_DISMISSED_BEFORE_INSTALLATION);
    TrackUserResponse(USER_RESPONSE_WEB_APP_DISMISSED);
    AppBannerSettingsHelper::RecordBannerDismissEvent(
        web_contents, shortcut_info_->url.spec(), AppBannerSettingsHelper::WEB);
  }
}

bool AppBannerUiDelegateAndroid::ShowDialog() {
  if (!weak_manager_.get())
    return false;

  JNIEnv* env = base::android::AttachCurrentThread();
  base::android::ScopedJavaLocalRef<jstring> java_app_title =
      base::android::ConvertUTF16ToJavaString(env, app_title_);

  DCHECK(!primary_icon_.drawsNothing());
  base::android::ScopedJavaLocalRef<jobject> java_bitmap =
      gfx::ConvertToJavaBitmap(&primary_icon_);

  if (IsForNativeApp()) {
    return Java_AppBannerUiDelegateAndroid_showNativeAppDialog(
        env, java_delegate_, java_app_title, java_bitmap, native_app_data_);
  }

  // Trim down the app URL to the origin. Banners only show on secure origins,
  // so elide the scheme.
  base::android::ScopedJavaLocalRef<jstring> java_app_url =
      base::android::ConvertUTF16ToJavaString(
          env, url_formatter::FormatUrlForSecurityDisplay(
                   shortcut_info_->url,
                   url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC));

  return Java_AppBannerUiDelegateAndroid_showWebAppDialog(
      env, java_delegate_, java_app_title, java_bitmap, java_app_url);
}

void AppBannerUiDelegateAndroid::ShowNativeAppDetails() {
  if (native_app_data_.is_null())
    return;

  Java_AppBannerUiDelegateAndroid_showAppDetails(
      base::android::AttachCurrentThread(), java_delegate_, native_app_data_);

  TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK);
}

void AppBannerUiDelegateAndroid::ShowNativeAppDetails(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& obj) {
  ShowNativeAppDetails();
}

AppBannerUiDelegateAndroid::AppBannerUiDelegateAndroid(
    base::WeakPtr<AppBannerManager> weak_manager,
    std::unique_ptr<ShortcutInfo> shortcut_info,
    const SkBitmap& primary_icon,
    const SkBitmap& badge_icon,
    WebappInstallSource install_source,
    bool is_webapk)
    : weak_manager_(weak_manager),
      app_title_(shortcut_info->name),
      shortcut_info_(std::move(shortcut_info)),
      primary_icon_(primary_icon),
      badge_icon_(badge_icon),
      type_(is_webapk ? AppType::WEBAPK : AppType::LEGACY_WEBAPP),
      install_source_(install_source),
      has_user_interaction_(false) {
  if (is_webapk)
    shortcut_info_->UpdateSource(ShortcutInfo::SOURCE_APP_BANNER_WEBAPK);
  else
    shortcut_info_->UpdateSource(ShortcutInfo::SOURCE_APP_BANNER);

  CreateJavaDelegate();
}

AppBannerUiDelegateAndroid::AppBannerUiDelegateAndroid(
    base::WeakPtr<AppBannerManager> weak_manager,
    const base::string16& app_title,
    const base::android::ScopedJavaLocalRef<jobject>& native_app_data,
    const SkBitmap& icon,
    const std::string& native_app_package_name)
    : weak_manager_(weak_manager),
      app_title_(app_title),
      native_app_data_(native_app_data),
      primary_icon_(icon),
      package_name_(native_app_package_name),
      type_(AppType::NATIVE),
      has_user_interaction_(false) {
  DCHECK(!native_app_data_.is_null());
  DCHECK(!package_name_.empty());
  CreateJavaDelegate();
}

void AppBannerUiDelegateAndroid::CreateJavaDelegate() {
  TabAndroid* tab = TabAndroid::FromWebContents(weak_manager_->web_contents());

  java_delegate_.Reset(Java_AppBannerUiDelegateAndroid_create(
      base::android::AttachCurrentThread(), reinterpret_cast<intptr_t>(this),
      tab->GetJavaObject()));
}

bool AppBannerUiDelegateAndroid::InstallOrOpenNativeApp() {
  DCHECK(IsForNativeApp());
  TrackUserResponse(USER_RESPONSE_NATIVE_APP_ACCEPTED);
  JNIEnv* env = base::android::AttachCurrentThread();

  bool was_opened = Java_AppBannerUiDelegateAndroid_installOrOpenNativeApp(
      env, java_delegate_, native_app_data_);

  if (was_opened)
    TrackDismissEvent(DISMISS_EVENT_APP_OPEN);
  else
    TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_TRIGGERED);

  return was_opened;
}

void AppBannerUiDelegateAndroid::InstallWebApk(
    content::WebContents* web_contents) {
  TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED);
  AppBannerSettingsHelper::RecordBannerInstallEvent(
      web_contents, shortcut_info_->url.spec(), AppBannerSettingsHelper::WEB);

  WebApkInstallService::Get(web_contents->GetBrowserContext())
      ->InstallAsync(web_contents, *shortcut_info_, primary_icon_, badge_icon_,
                     install_source_);
}

void AppBannerUiDelegateAndroid::InstallLegacyWebApp(
    content::WebContents* web_contents) {
  DCHECK_EQ(AppType::LEGACY_WEBAPP, GetType());

  TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED);

  AppBannerSettingsHelper::RecordBannerInstallEvent(
      web_contents, shortcut_info_->url.spec(), AppBannerSettingsHelper::WEB);

  // TODO(https://crbug.com/861643): Support maskable icons here.
  ShortcutHelper::AddToLauncherWithSkBitmap(web_contents, *shortcut_info_,
                                            primary_icon_,
                                            /*is_icon_maskable=*/false);
}

void AppBannerUiDelegateAndroid::SendBannerAccepted() {
  if (!weak_manager_)
    return;

  weak_manager_->SendBannerAccepted();

  // Send the appinstalled event and perform install time logging. Note that
  // this is only done for webapps as native apps just intent to the Play store.
  // Also this event is fired *before* the installation actually takes place
  // (which can be a significant amount of time later, especially if using
  // WebAPKs).
  // TODO(mgiuca): Fire the event *after* the installation is completed.
  if (!IsForNativeApp())
    weak_manager_->OnInstall(/*is_native=*/false, shortcut_info_->display);
}

}  // namespace banners
