// 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 "base/strings/to_string.h"
#include "chrome/browser/web_applications/web_app_install_info.h"
#include "chrome/browser/web_applications/web_app_install_utils.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 "components/webapps/browser/web_contents/web_app_url_loader.h"
#include "components/webapps/common/web_app_id.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::Dict InstallErrorLogEntry::TakeErrorDict() {
  DCHECK(error_dict_);
  base::Value::Dict error_dict = std::move(*error_dict_);
  *error_dict_ = base::Value::Dict();
  return error_dict;
}

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

  base::Value::Dict url_loader_error;

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

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

void InstallErrorLogEntry::LogExpectedAppIdError(
    const char* stage,
    const std::string& url,
    const webapps::AppId& app_id,
    const webapps::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.url;
      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("icon_size",
                            url_and_http_code.first.size.ToString());
        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
