// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/feedback/feedback_common.h"

#include <algorithm>
#include <utility>

#include "base/containers/span.h"
#include "base/files/file_path.h"
#include "base/json/json_reader.h"
#include "base/memory/ptr_util.h"
#include "base/strings/to_string.h"
#include "base/values.h"
#include "components/feedback/feedback_constants.h"
#include "components/feedback/feedback_report.h"
#include "components/feedback/feedback_util.h"
#include "components/feedback/proto/common.pb.h"
#include "components/feedback/proto/dom.pb.h"
#include "components/feedback/proto/extension.pb.h"
#include "components/feedback/proto/math.pb.h"
#include "google_apis/gaia/gaia_auth_util.h"

#if BUILDFLAG(IS_CHROMEOS)
#include "ash/constants/ash_features.h"
#endif

namespace {

// The below thresholds were chosen arbitrarily to conveniently show small data
// as part of the report itself without having to look into the system_logs.zip
// file.
constexpr size_t kFeedbackMaxLength = 1024;
constexpr size_t kFeedbackMaxLineCount = 10;

constexpr base::FilePath::CharType kLogsFilename[] =
    FILE_PATH_LITERAL("system_logs.txt");
constexpr char kLogsAttachmentName[] = "system_logs.zip";

constexpr char kZipExt[] = ".zip";

constexpr char kPngMimeType[] = "image/png";
constexpr char kArbitraryMimeType[] = "application/octet-stream";

#if BUILDFLAG(IS_CHROMEOS)
// Keep in sync with
// google3/java/com/google/wireless/android/tools/betterbug/protos/uploadfeedbackreport.proto.
constexpr char kIsCrossDeviceIssueKey[] = "is_cross_device_issue";
constexpr char kIsCrossDeviceIssueTrueValue[] = "true";
constexpr char kTargetDeviceIdKey[] = "target_device_id";
constexpr char kTargetDeviceIdTypeKey[] = "target_device_id_type";
constexpr char kInitiatingDeviceName[] = "initiating_device_name";
// Enum value for MAC_ADDRESS type.
constexpr char kTargetDeviceIdTypeMacAddressValue[] = "1";
constexpr char kInitiatingDeviceNameValue[] = "Chromebook";
#endif  // BUILDFLAG(IS_CHROMEOS)

constexpr char kIsOffensiveOrUnsafeKey[] = "is_offensive_or_unsafe";

// Determine if the given feedback value is small enough to not need to
// be compressed.
bool BelowCompressionThreshold(const std::string& content) {
  if (content.length() > kFeedbackMaxLength)
    return false;
  const size_t line_count = std::ranges::count(content, '\n');
  if (line_count > kFeedbackMaxLineCount)
    return false;
  return true;
}

void AddFeedbackData(userfeedback::ExtensionSubmit* feedback_data,
                     const std::string& key,
                     const std::string& value) {
  // Don't bother with empty keys or values.
  if (key.empty() || value.empty())
    return;
  // Create log_value object and add it to the web_data object.
  userfeedback::ProductSpecificData log_value;
  log_value.set_key(key);
  log_value.set_value(value);
  userfeedback::WebData* web_data = feedback_data->mutable_web_data();
  *(web_data->add_product_specific_data()) = log_value;
}

// Adds data as an attachment to feedback_data if the data is non-empty.
void AddAttachment(userfeedback::ExtensionSubmit* feedback_data,
                   const char* name,
                   const std::vector<uint8_t>& data) {
  if (data.empty())
    return;

  userfeedback::ProductSpecificBinaryData* attachment =
      feedback_data->add_product_specific_binary_data();
  attachment->set_mime_type(kArbitraryMimeType);
  attachment->set_name(name);
  attachment->set_data(data.data(), data.size());
}

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// FeedbackCommon::AttachedFile::
////////////////////////////////////////////////////////////////////////////////

FeedbackCommon::AttachedFile::AttachedFile(const std::string& filename,
                                           std::vector<uint8_t> data)
    : name(filename), data(std::move(data)) {}

FeedbackCommon::AttachedFile::~AttachedFile() = default;

FeedbackCommon::AttachedFile::AttachedFile(FeedbackCommon::AttachedFile&&) =
    default;

FeedbackCommon::AttachedFile& FeedbackCommon::AttachedFile::operator=(
    FeedbackCommon::AttachedFile&&) = default;

////////////////////////////////////////////////////////////////////////////////
// FeedbackCommon::
////////////////////////////////////////////////////////////////////////////////

FeedbackCommon::FeedbackCommon() : product_id_(-1) {}

void FeedbackCommon::AddFile(const std::string& filename, std::string data) {
  base::AutoLock lock(attachments_lock_);
  base::span<const uint8_t> byte_span = base::as_byte_span(data);
  attachments_.emplace_back(
      filename, std::vector<uint8_t>(byte_span.begin(), byte_span.end()));
}

void FeedbackCommon::AddFile(const std::string& filename,
                             std::vector<uint8_t> data) {
  base::AutoLock lock(attachments_lock_);
  attachments_.emplace_back(filename, std::move(data));
}

void FeedbackCommon::AddLog(std::string name, std::string value) {
  logs_[std::move(name)] = std::move(value);
}

void FeedbackCommon::AddLogs(SystemLogsMap logs) {
  // The empty logs_ case is just an optimization.
  if (logs_.empty())
    logs_ = std::move(logs);
  else
    logs.insert(logs.begin(), logs.end());
}

bool FeedbackCommon::RemoveLog(std::string name) {
  return logs_.erase(name) == 1;
}

void FeedbackCommon::PrepareReport(
    userfeedback::ExtensionSubmit* feedback_data) const {
  // Unused field, needs to be 0 though.
  feedback_data->set_type_id(0);

  // Set whether we're reporting from ChromeOS or Chrome on another platform.
  userfeedback::ChromeData chrome_data;
#if BUILDFLAG(IS_CHROMEOS)
  const userfeedback::ChromeData_ChromePlatform chrome_platform =
      userfeedback::ChromeData_ChromePlatform_CHROME_OS;
  const int default_product_id = feedback::kChromeOSProductId;
  userfeedback::ChromeOsData chrome_os_data;
  chrome_os_data.set_category(
      userfeedback::ChromeOsData_ChromeOsCategory_OTHER);
  *(chrome_data.mutable_chrome_os_data()) = chrome_os_data;
#else
  const userfeedback::ChromeData_ChromePlatform chrome_platform =
      userfeedback::ChromeData_ChromePlatform_CHROME_BROWSER;
  const int default_product_id = feedback::kChromeBrowserProductId;
  userfeedback::ChromeBrowserData chrome_browser_data;
  chrome_browser_data.set_category(
      userfeedback::ChromeBrowserData_ChromeBrowserCategory_OTHER);
  *(chrome_data.mutable_chrome_browser_data()) = chrome_browser_data;
#endif  // BUILDFLAG(IS_CHROMEOS)
  chrome_data.set_chrome_platform(chrome_platform);
  // TODO(b/301518187): Investigate if this line is needed in order for custom
  // product IDs to work. Remove `include_chrome_platform_` if it's not needed.
  if (include_chrome_platform_) {
    *(feedback_data->mutable_chrome_data()) = chrome_data;
  }

  feedback_data->set_product_id(HasProductId() ? product_id_
                                               : default_product_id);

  userfeedback::CommonData* common_data = feedback_data->mutable_common_data();
  // We're not using gaia ids, we're using the e-mail field instead.
  common_data->set_gaia_id(0);
  common_data->set_user_email(user_email());
  common_data->set_description(description());
  common_data->set_source_description_language(locale());

  userfeedback::WebData* web_data = feedback_data->mutable_web_data();
  if (!page_url().empty()) {
    web_data->set_url(page_url());
  }
  web_data->mutable_navigator()->set_user_agent(user_agent());

  AddFilesAndLogsToReport(feedback_data);

  if (image().size()) {
    userfeedback::PostedScreenshot screenshot;
    if (image_mime_type().empty()) {
      screenshot.set_mime_type(kPngMimeType);
    } else {
      screenshot.set_mime_type(image_mime_type());
    }

    // Set that we 'have' dimensions of the screenshot. These dimensions are
    // ignored by the server but are a 'required' field in the protobuf.
    userfeedback::Dimensions dimensions;
    dimensions.set_width(0.0);
    dimensions.set_height(0.0);

    *(screenshot.mutable_dimensions()) = dimensions;
    screenshot.set_binary_content(image());

    *(feedback_data->mutable_screenshot()) = screenshot;
  }

  if (category_tag().size())
    feedback_data->set_bucket(category_tag());
#if BUILDFLAG(IS_CHROMEOS)
  if (ash::features::IsLinkCrossDeviceDogfoodFeedbackEnabled() &&
      gaia::IsGoogleInternalAccountEmail(user_email()) &&
      mac_address_.has_value()) {
    AddFeedbackData(feedback_data, kIsCrossDeviceIssueKey,
                    kIsCrossDeviceIssueTrueValue);
    AddFeedbackData(feedback_data, kTargetDeviceIdKey, mac_address_.value());
    AddFeedbackData(feedback_data, kTargetDeviceIdTypeKey,
                    kTargetDeviceIdTypeMacAddressValue);
    AddFeedbackData(feedback_data, kInitiatingDeviceName,
                    kInitiatingDeviceNameValue);
  }
#endif  // BUILDFLAG(IS_CHROMEOS)

  if (is_offensive_or_unsafe_.has_value()) {
    AddFeedbackData(feedback_data, kIsOffensiveOrUnsafeKey,
                    base::ToString(is_offensive_or_unsafe_.value()));
  }
  if (!ai_metadata_.empty()) {
    // Add feedback data for each key/value pair.
    std::optional<base::Value::Dict> dict = base::JSONReader::ReadDict(
        ai_metadata_, base::JSON_PARSE_CHROMIUM_EXTENSIONS);
    CHECK(dict);
    for (auto pair : dict.value()) {
      AddFeedbackData(feedback_data, pair.first, pair.second.GetString());
    }
  }
}

void FeedbackCommon::RedactDescription(redaction::RedactionTool& redactor) {
  description_ = redactor.Redact(description_);
}

// static
bool FeedbackCommon::IncludeInSystemLogs(const std::string& key,
                                         bool is_google_email) {
  return is_google_email ||
         key != feedback::FeedbackReport::kAllCrashReportIdsKey;
}

// static
int FeedbackCommon::GetChromeBrowserProductId() {
  return feedback::kChromeBrowserProductId;
}

// static
int FeedbackCommon::GetMahiProductId() {
  return feedback::kMahiFeedbackProductId;
}

#if BUILDFLAG(IS_CHROMEOS)
// static
int FeedbackCommon::GetChromeOSProductId() {
  return feedback::kChromeOSProductId;
}
#endif  // BUILDFLAG(IS_CHROMEOS)

FeedbackCommon::~FeedbackCommon() = default;

void FeedbackCommon::CompressFile(const base::FilePath& filename,
                                  const std::string& zipname,
                                  std::string data_to_be_compressed) {
  std::optional<std::string> compressed_data =
      feedback_util::ZipString(filename, data_to_be_compressed);
  if (!compressed_data.has_value()) {
    return;
  }

  std::string attachment_file_name = zipname;
  if (attachment_file_name.empty()) {
    // We need to use the UTF8Unsafe methods here to accommodate Windows,
    // which uses wide strings to store file paths.
    attachment_file_name = filename.BaseName().AsUTF8Unsafe().append(kZipExt);
  }

  AddFile(attachment_file_name, std::move(compressed_data.value()));
}

void FeedbackCommon::CompressLogs() {
  // Convert the system logs into a string that we can compress and send with
  // the report.
  std::string logs = feedback_util::LogsToString(logs_);
  if (!logs.empty()) {
    CompressFile(base::FilePath(kLogsFilename), kLogsAttachmentName,
                 std::move(logs));
  }
}

void FeedbackCommon::AddFilesAndLogsToReport(
    userfeedback::ExtensionSubmit* feedback_data) const {
  for (size_t i = 0; i < attachments(); ++i) {
    const AttachedFile* file = attachment(i);
    AddAttachment(feedback_data, file->name.c_str(), file->data);
  }

  const bool is_google_email = gaia::IsGoogleInternalAccountEmail(user_email());
  for (const auto& iter : logs_) {
    if (BelowCompressionThreshold(iter.second)) {
      // We only send the list of all the crash report IDs if the user has a
      // @google.com email. We do this also in feedback_private_api, but not all
      // code paths go through that so we need to check again here.
      if (FeedbackCommon::IncludeInSystemLogs(iter.first, is_google_email)) {
        // Small enough logs should end up in the report data itself. However,
        // they're still added as part of the system_logs.zip file.
        AddFeedbackData(feedback_data, iter.first, iter.second);
      }
    }
  }
}
