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

#include <string>

#include "base/feature_list.h"
#include "chrome/browser/web_applications/web_app_id.h"
#include "chrome/browser/web_applications/web_app_install_info.h"
#include "chrome/browser/web_applications/web_app_url_loader.h"
#include "chrome/browser/web_applications/web_app_utils.h"
#include "chrome/common/chrome_features.h"
#include "components/webapps/browser/installable/installable_metrics.h"
#include "net/http/http_status_code.h"

namespace web_app {
namespace {

bool IsEmptyIconBitmapsForIconUrl(const IconsMap& icons_map,
                                  const GURL& icon_url) {
  IconsMap::const_iterator iter = icons_map.find(icon_url);
  if (iter == icons_map.end())
    return true;

  const std::vector<SkBitmap>& icon_bitmaps = iter->second;
  if (icon_bitmaps.empty())
    return true;

  for (const SkBitmap& icon_bitmap : icon_bitmaps) {
    if (!icon_bitmap.isNull() && !icon_bitmap.drawsNothing())
      return false;
  }

  return true;
}

}  // namespace

InstallErrorLogEntry::InstallErrorLogEntry(
    bool background_installation,
    webapps::WebappInstallSource install_surface)
    : background_installation_(background_installation),
      install_surface_(install_surface) {
  if (base::FeatureList::IsEnabled(features::kRecordWebAppDebugInfo))
    error_dict_ = std::make_unique<base::Value::Dict>();
}

InstallErrorLogEntry::~InstallErrorLogEntry() = default;

base::Value InstallErrorLogEntry::TakeErrorDict() {
  DCHECK(error_dict_);
  base::Value error_dict = base::Value(std::move(*error_dict_));
  *error_dict_ = base::Value::Dict();
  return error_dict;
}

void InstallErrorLogEntry::LogUrlLoaderError(const char* stage,
                                             const std::string& url,
                                             WebAppUrlLoader::Result result) {
  if (!error_dict_)
    return;

  base::Value::Dict url_loader_error;

  url_loader_error.Set("WebAppUrlLoader::Result",
                       ConvertUrlLoaderResultToString(result));

  LogErrorObject(stage, url, std::move(url_loader_error));
}

void InstallErrorLogEntry::LogExpectedAppIdError(const char* stage,
                                                 const std::string& url,
                                                 const AppId& app_id,
                                                 const AppId& expected_app_id) {
  if (!error_dict_)
    return;

  base::Value::Dict expected_app_id_error;
  expected_app_id_error.Set("expected_app_id", expected_app_id);
  expected_app_id_error.Set("app_id", app_id);

  LogErrorObject(stage, url, std::move(expected_app_id_error));
}

void InstallErrorLogEntry::LogDownloadedIconsErrors(
    const WebAppInstallInfo& web_app_info,
    IconsDownloadedResult icons_downloaded_result,
    const IconsMap& icons_map,
    const DownloadedIconsHttpResults& icons_http_results) {
  if (!error_dict_)
    return;

  base::Value::Dict icon_errors;
  {
    // Reports errors only, omits successful entries.
    base::Value::List icons_http_errors;

    for (const auto& url_and_http_code : icons_http_results) {
      const GURL& icon_url = url_and_http_code.first;
      int http_status_code = url_and_http_code.second;
      const char* http_code_desc = net::GetHttpReasonPhrase(
          static_cast<net::HttpStatusCode>(http_status_code));

      // If the SkBitmap for`icon_url` is missing in `icons_map` then we report
      // this miss as an error, even for net::HttpStatusCode::HTTP_OK.
      if (IsEmptyIconBitmapsForIconUrl(icons_map, icon_url)) {
        base::Value::Dict icon_http_error;

        icon_http_error.Set("icon_url", icon_url.spec());
        icon_http_error.Set("http_status_code", http_status_code);
        icon_http_error.Set("http_code_desc", http_code_desc);

        icons_http_errors.Append(std::move(icon_http_error));
      }
    }

    if (icons_downloaded_result != IconsDownloadedResult::kCompleted ||
        !icons_http_errors.empty()) {
      icon_errors.Set("icons_downloaded_result",
                      IconsDownloadedResultToString(icons_downloaded_result));
    }

    if (!icons_http_errors.empty())
      icon_errors.Set("icons_http_results", std::move(icons_http_errors));
  }

  if (web_app_info.is_generated_icon)
    icon_errors.Set("is_generated_icon", true);

  if (!icon_errors.empty()) {
    LogErrorObject("OnIconsRetrieved", web_app_info.start_url.spec(),
                   std::move(icon_errors));
  }
}

void InstallErrorLogEntry::LogHeaderIfLogEmpty(const std::string& url) {
  if (!error_dict_ || !error_dict_->empty())
    return;

  error_dict_->Set("!url", url);
  error_dict_->Set("install_surface", static_cast<int>(install_surface_));
  error_dict_->Set("background_installation", background_installation_);
  error_dict_->Set("stages", base::Value::List());
}

void InstallErrorLogEntry::LogErrorObject(const char* stage,
                                          const std::string& url,
                                          base::Value::Dict object) {
  if (!error_dict_)
    return;

  LogHeaderIfLogEmpty(url);

  object.Set("!stage", stage);
  error_dict_->FindList("stages")->Append(std::move(object));
}

}  // namespace web_app
