// Copyright 2022 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/browser/web_applications/manifest_update_utils.h"

#include <ostream>
#include <string>

#include "base/feature_list.h"
#include "base/metrics/histogram_functions.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_constants.h"
#include "chrome/browser/web_applications/web_app_install_utils.h"
#include "chrome/browser/web_applications/web_app_management_type.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/common/chrome_features.h"
#include "components/webapps/common/web_app_id.h"
#include "content/public/common/url_constants.h"
#include "third_party/blink/public/common/features.h"
#include "ui/gfx/skia_util.h"

namespace web_app {

std::ostream& operator<<(std::ostream& os, ManifestUpdateResult result) {
  switch (result) {
    case ManifestUpdateResult::kNoAppInScope:
      return os << "kNoAppInScope";
    case ManifestUpdateResult::kThrottled:
      return os << "kThrottled";
    case ManifestUpdateResult::kWebContentsDestroyed:
      return os << "kWebContentsDestroyed";
    case ManifestUpdateResult::kAppUninstalling:
      return os << "kAppUninstalling";
    case ManifestUpdateResult::kAppIsPlaceholder:
      return os << "kAppIsPlaceholder";
    case ManifestUpdateResult::kAppUpToDate:
      return os << "kAppUpToDate";
    case ManifestUpdateResult::kAppNotEligible:
      return os << "kAppNotEligible";
    case ManifestUpdateResult::kAppUpdateFailed:
      return os << "kAppUpdateFailed";
    case ManifestUpdateResult::kAppUpdated:
      return os << "kAppUpdated";
    case ManifestUpdateResult::kAppIsSystemWebApp:
      return os << "kAppIsSystemWebApp";
    case ManifestUpdateResult::kIconDownloadFailed:
      return os << "kIconDownloadFailed";
    case ManifestUpdateResult::kIconReadFromDiskFailed:
      return os << "kIconReadFromDiskFailed";
    case ManifestUpdateResult::kAppIdMismatch:
      return os << "kAppIdMismatch";
    case ManifestUpdateResult::kSystemShutdown:
      return os << "kSystemShutdown";
    case ManifestUpdateResult::kAppIdentityUpdateRejectedAndUninstalled:
      return os << "kAppIdentityUpdateRejectedAndUninstalled";
    case ManifestUpdateResult::kAppIsIsolatedWebApp:
      return os << "kAppIsIsolatedWebApp";
    case ManifestUpdateResult::kCancelledDueToMainFrameNavigation:
      return os << "kCancelledDueToMainFrameNavigation";
    case ManifestUpdateResult::kShortcutIgnoresManifest:
      return os << "kkShortcutIgnoresManifest";
  }
}

std::ostream& operator<<(std::ostream& os, ManifestUpdateCheckStage stage) {
  switch (stage) {
    case ManifestUpdateCheckStage::kPendingAppLock:
      return os << "kPendingAppLock";
    case ManifestUpdateCheckStage::kDownloadingNewManifestData:
      return os << "kDownloadingNewManifestData";
    case ManifestUpdateCheckStage::kLoadingExistingManifestData:
      return os << "kLoadingExistingManifestData";
    case ManifestUpdateCheckStage::kComparingManifestData:
      return os << "kComparingManifestData";
    case ManifestUpdateCheckStage::kResolvingIdentityChanges:
      return os << "kResolvingIdentityChanges";
    case ManifestUpdateCheckStage::kComplete:
      return os << "kComplete";
  }
}

std::ostream& operator<<(std::ostream& os, ManifestUpdateCheckResult stage) {
  switch (stage) {
    case ManifestUpdateCheckResult::kAppIdMismatch:
      return os << "kAppIdMismatch";
    case ManifestUpdateCheckResult::kAppNotEligible:
      return os << "kAppNotEligible";
    case ManifestUpdateCheckResult::kSystemShutdown:
      return os << "kSystemShutdown";
    case ManifestUpdateCheckResult::kAppUpdateNeeded:
      return os << "kAppUpdateNeeded";
    case ManifestUpdateCheckResult::kAppIdentityUpdateRejectedAndUninstalled:
      return os << "kAppIdentityUpdateRejectedAndUninstalled";
    case ManifestUpdateCheckResult::kAppUpToDate:
      return os << "kAppUpToDate";
    case ManifestUpdateCheckResult::kIconDownloadFailed:
      return os << "kIconDownloadFailed";
    case ManifestUpdateCheckResult::kIconReadFromDiskFailed:
      return os << "kIconReadFromDiskFailed";
    case ManifestUpdateCheckResult::kWebContentsDestroyed:
      return os << "kWebContentsDestroyed";
    case ManifestUpdateCheckResult::kCancelledDueToMainFrameNavigation:
      return os << "kCancelledDueToMainFrameNavigation";
  }
}

ManifestUpdateResult FinalResultFromManifestUpdateCheckResult(
    ManifestUpdateCheckResult check_result) {
  switch (check_result) {
    case ManifestUpdateCheckResult::kAppIdMismatch:
      return ManifestUpdateResult::kAppIdMismatch;
    case ManifestUpdateCheckResult::kAppNotEligible:
      return ManifestUpdateResult::kAppNotEligible;
    case ManifestUpdateCheckResult::kSystemShutdown:
      return ManifestUpdateResult::kSystemShutdown;
    case ManifestUpdateCheckResult::kAppUpdateNeeded:
      // The manifest needs to be applied before the overall update process is
      // considered complete.
      NOTREACHED();
    case ManifestUpdateCheckResult::kAppUpToDate:
      return ManifestUpdateResult::kAppUpToDate;
    case ManifestUpdateCheckResult::kAppIdentityUpdateRejectedAndUninstalled:
      return ManifestUpdateResult::kAppIdentityUpdateRejectedAndUninstalled;
    case ManifestUpdateCheckResult::kIconDownloadFailed:
      return ManifestUpdateResult::kIconDownloadFailed;
    case ManifestUpdateCheckResult::kIconReadFromDiskFailed:
      return ManifestUpdateResult::kIconReadFromDiskFailed;
    case ManifestUpdateCheckResult::kWebContentsDestroyed:
      return ManifestUpdateResult::kWebContentsDestroyed;
    case ManifestUpdateCheckResult::kCancelledDueToMainFrameNavigation:
      return ManifestUpdateResult::kCancelledDueToMainFrameNavigation;
  }
}

std::optional<AppIconIdentityChange> CompareIdentityIconBitmaps(
    const IconBitmaps& existing_app_icon_bitmaps,
    const IconBitmaps& new_app_icon_bitmaps) {
  for (IconPurpose purpose : kIconPurposes) {
    const std::map<SquareSizePx, SkBitmap>& existing_bitmaps =
        existing_app_icon_bitmaps.GetBitmapsForPurpose(purpose);
    const std::map<SquareSizePx, SkBitmap>& new_bitmaps =
        new_app_icon_bitmaps.GetBitmapsForPurpose(purpose);

    for (SquareSizePx size : kIdentitySizes) {
      auto existing_it = existing_bitmaps.find(size);
      if (existing_it == existing_bitmaps.end()) {
        continue;
      }
      auto new_it = new_bitmaps.find(size);
      if (new_it == new_bitmaps.end()) {
        continue;
      }

      const SkBitmap& existing_bitmap = existing_it->second;
      const SkBitmap& new_bitmap = new_it->second;

      if (!gfx::BitmapsAreEqual(existing_bitmap, new_bitmap)) {
        return AppIconIdentityChange{.before = existing_bitmap,
                                     .after = new_bitmap};
      }
    }
  }
  return std::nullopt;
}

bool CanWebAppSilentlyUpdateIdentity(const WebApp& web_app) {
  if (web_app.IsPolicyInstalledApp() &&
      base::FeatureList::IsEnabled(
          features::kWebAppManifestPolicyAppIdentityUpdate)) {
    return true;
  }
  if (web_app.scope().SchemeIs(content::kChromeUIScheme)) {
    return true;
  }

  // The `!web_app.IsPolicyInstalledApp()` hack is to ensure that the "existing"
  // manifest update process only works for policy installed apps if
  // `kWebAppManifestPolicyAppIdentityUpdate` is enabled, for browser tests.
  // Once predictable app updating lands, this code will be removed (since that
  // feature flag is enabled by default anyway).
  return !web_app.IsPolicyInstalledApp() &&
         web_app.WasInstalledByTrustedSources();
}

bool CanShowIdentityUpdateConfirmationDialog(const WebAppRegistrar& registrar,
                                             const WebApp& web_app) {
  DCHECK(!CanWebAppSilentlyUpdateIdentity(web_app));

  if (web_app.IsPolicyInstalledApp()) {
    return false;
  }

  // Shortcut apps may immediately trigger the identity updating if the user
  // has overridden the title of the app, see: https://crbug.com/1366600
  // Don't show the update prompt for shortcut apps and always revert.
  if (registrar.GetLatestAppInstallSource(web_app.app_id()) ==
      webapps::WebappInstallSource::MENU_CREATE_SHORTCUT) {
    return false;
  }

  return true;
}

ManifestDataChanges::ManifestDataChanges() = default;
ManifestDataChanges::ManifestDataChanges(ManifestDataChanges&&) = default;
ManifestDataChanges& ManifestDataChanges::operator=(ManifestDataChanges&&) =
    default;
ManifestDataChanges::~ManifestDataChanges() = default;

ManifestDataChanges GetManifestDataChanges(
    const WebApp& existing_web_app,
    const IconBitmaps* existing_app_icon_bitmaps,
    const ShortcutsMenuIconBitmaps* existing_shortcuts_menu_icon_bitmaps,
    const WebAppInstallInfo& new_install_info) {
  ManifestDataChanges result;

  // TODO(crbug.com/40201597): Check whether translations have been updated.
  result.app_name_changed =
      new_install_info.title.value() !=
      base::UTF8ToUTF16(existing_web_app.untranslated_name());

  // TODO(crbug.com/40254036): Run these bitmap comparisons off the UI thread.
  if (existing_app_icon_bitmaps) {
    result.app_icon_identity_change = CompareIdentityIconBitmaps(
        *existing_app_icon_bitmaps, new_install_info.icon_bitmaps);
  }

  result.any_app_icon_changed =
      result.app_icon_identity_change ||
      existing_web_app.manifest_icons() != new_install_info.manifest_icons ||
      (existing_app_icon_bitmaps &&
       *existing_app_icon_bitmaps != new_install_info.icon_bitmaps);

  result.other_fields_changed = [&] {
    if (existing_web_app.manifest_id() != new_install_info.manifest_id()) {
      return true;
    }
    if (existing_web_app.start_url() != new_install_info.start_url()) {
      return true;
    }
    if (existing_web_app.theme_color() != new_install_info.theme_color) {
      return true;
    }
    if (existing_web_app.scope() != new_install_info.scope) {
      return true;
    }
    if (existing_web_app.display_mode() != new_install_info.display_mode) {
      return true;
    }
    if (existing_web_app.display_mode_override() !=
        new_install_info.display_override) {
      return true;
    }
    if (existing_web_app.shortcuts_menu_item_infos() !=
        new_install_info.shortcuts_menu_item_infos) {
      return true;
    }
    if (existing_web_app.share_target() != new_install_info.share_target) {
      return true;
    }
    if (existing_web_app.protocol_handlers() !=
        new_install_info.protocol_handlers) {
      return true;
    }
    if (base::FeatureList::IsEnabled(
            blink::features::kWebAppManifestLockScreen) &&
        existing_web_app.lock_screen_start_url() !=
            new_install_info.lock_screen_start_url) {
      return true;
    }
    if (existing_web_app.note_taking_new_note_url() !=
        new_install_info.note_taking_new_note_url) {
      return true;
    }
    if (existing_web_app.file_handlers() != new_install_info.file_handlers) {
      return true;
    }
    if (existing_web_app.background_color() !=
        new_install_info.background_color) {
      return true;
    }
    if (existing_web_app.dark_mode_theme_color() !=
        new_install_info.dark_mode_theme_color) {
      return true;
    }
    if (existing_web_app.dark_mode_background_color() !=
        new_install_info.dark_mode_background_color) {
      return true;
    }
    if (existing_web_app.manifest_url() != new_install_info.manifest_url) {
      return true;
    }
    if (existing_web_app.launch_handler() != new_install_info.launch_handler) {
      return true;
    }
    if (existing_web_app.permissions_policy() !=
        new_install_info.permissions_policy) {
      return true;
    }
    if (existing_shortcuts_menu_icon_bitmaps &&
        *existing_shortcuts_menu_icon_bitmaps !=
            new_install_info.shortcuts_menu_icon_bitmaps) {
      return true;
    }
    if (existing_web_app.scope_extensions() !=
        new_install_info.scope_extensions) {
      return true;
    }
    if (new_install_info.validated_scope_extensions.has_value() &&
        existing_web_app.validated_scope_extensions() !=
            new_install_info.validated_scope_extensions.value()) {
      return true;
    }
    if (existing_web_app.tab_strip() != new_install_info.tab_strip) {
      return true;
    }
    if (existing_web_app.related_applications() !=
        new_install_info.related_applications) {
      return true;
    }
    // TODO(crbug.com/40611449): Check more manifest fields.
    return false;
  }();

  return result;
}

void RecordIdentityConfirmationMetrics(
    const ManifestDataChanges& manifest_data_changes,
    const WebApp& web_app) {
  // This is used for metrics, so do not remove or reorder existing entries.
  enum AppIdentityDisplayMetric {
    kNoAppIdentityChange = 0,
    kIconChanging = 1,
    // Values 2 and 3 are reserved for Android (icon mask).
    kAppNameChanging = 4,
    kAppNameAndIconChanging = 5,
    // Values 6 through 15 (inclusive) are reserved for Android (icon mask/app
    // short name).
    kLastAndroidSpecificValue = 29,

    // Add any new values above this one, and update kMaxValue to the highest
    // enumerator value.
    kMaxValue = kLastAndroidSpecificValue,
  };

  AppIdentityDisplayMetric app_id_changes = [&] {
    if (manifest_data_changes.app_name_changed &&
        manifest_data_changes.app_icon_identity_change) {
      return kAppNameAndIconChanging;
    }
    if (manifest_data_changes.app_name_changed) {
      return kAppNameChanging;
    }
    if (manifest_data_changes.app_icon_identity_change) {
      return kIconChanging;
    }
    return kNoAppIdentityChange;
  }();

  if (manifest_data_changes.RequiresConfirmation()) {
    base::UmaHistogramEnumeration("Webapp.AppIdentityDialog.Showing",
                                  app_id_changes);
    return;
  }

  if (manifest_data_changes.app_name_identity_update_decision ==
          IdentityUpdateDecision::kSilentlyAllow ||
      manifest_data_changes.app_icon_identity_update_decision ==
          IdentityUpdateDecision::kSilentlyAllow) {
    base::UmaHistogramEnumeration("Webapp.AppIdentityDialog.AlreadyApproved",
                                  app_id_changes);
    return;
  }

  base::UmaHistogramEnumeration("Webapp.AppIdentityDialog.NotShowing",
                                app_id_changes);
}

}  // namespace web_app
