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

#include <iterator>
#include <string>

#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/task/single_thread_task_executor.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/values.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"
#include "tools/aggregation_service/aggregation_service_tool.h"
#include "url/gurl.h"
#include "url/origin.h"
#include "url/url_canon.h"

namespace {

// If you change any of the switch strings, update the `kHelpMsg`,
// `kAllowedSwitches` and `kRequiredSwitches` accordingly.
constexpr char kSwitchHelp[] = "help";
constexpr char kSwitchHelpShort[] = "h";
constexpr char kSwitchOperation[] = "operation";
constexpr char kSwitchBucket[] = "bucket";
constexpr char kSwitchValue[] = "value";
constexpr char kSwitchAlternativeAggregationMode[] =
    "alternative-aggregation-mode";
constexpr char kSwitchReportingOrigin[] = "reporting-origin";
constexpr char kSwitchHelperKeyUrls[] = "helper-key-urls";
constexpr char kSwitchHelperKeyFiles[] = "helper-key-files";
constexpr char kSwitchOutputFile[] = "output-file";
constexpr char kSwitchOutputUrl[] = "output-url";
constexpr char kSwitchDisablePayloadEncryption[] = "disable-payload-encryption";
constexpr char kSwitchAdditionalFields[] = "additional-fields";
constexpr char kSwitchAdditionalSharedInfoFields[] =
    "additional-shared-info-fields";
constexpr char kSwitchEnableDebugMode[] = "enable-debug-mode";
constexpr char kSwitchApiVersion[] = "api-version";
constexpr char kSwitchApi[] = "api";

constexpr char kHelpMsg[] = R"(
  aggregation_service_tool [--operation=<operation>] --bucket=<bucket>
  --value=<value> --aggregation-mode=<aggregation_mode>
  --reporting-origin=<reporting_origin>
  --helper-keys=<helper_server_keys> [--output=<output_file>]
  [--output-url=<output_url>] [--disable-payload-encryption]
  [--additional-fields=<additional_fields>]
  [--additional-shared-info-fields=<additional_shared_info_fields]
  [--debug-mode] [--api-version=<api_version>] [--api=<api_identifier>]

  Examples:
  aggregation_service_tool --operation="histogram" --bucket=1234 --value=5
  --alternative-aggregation-mode="experimental-poplar" --reporting-origin="https://example.com"
  --helper-key-urls="https://a.com/keys.json https://b.com/path/to/keys.json"
  --output-file="output.json" --enable-debug-mode --api-version="1.0"
  --api="attribution-reporting" --additional-fields=
  "source_site=https://publisher.example,attribution_destination=https://advertiser.example"
  or
  aggregation_service_tool --bucket=1234 --value=5
  --reporting-origin="https://example.com"
  --helper-key-files="keys.json"
  --output-url="https://c.com/reports"

  aggregation_service_tool is a command-line tool that accepts report contents
  and mapping of origins to public key json files as input and either output an
  aggregatable report to a file on disk or send the aggregatable report to an
  endpoint origin over network. `scheduled_report_time` will be default to 30
  seconds later.

  Switches:
  --operation = Optional switch. Currently only supports "histogram". Default is
                "histogram".
  --bucket = Bucket key of the histogram contribution, must be non-negative
             integer.
  --value = Bucket value of the histogram contribution, must be non-negative
            integer.
  --alternative-aggregation-mode = Optional switch to specify an alternative
                                   aggregation mode. Supports "tee-based",
                                   "experimental-poplar" and "default"
                                   (default value, equivalent to "tee-based").
  --reporting-origin = The reporting origin endpoint.
  --helper-key-urls = Optional switch to specify the URL(s) to fetch the public
                      key json file(s) from. Spaces are used as separators.
                      Either this or "--helper-key-files" must be specified.
  --helper-key-files = Optional switch to specify the local public key json
                       file(s) to use. Spaces are used as separators. Either
                       this or "--helper-key-urls" must be specified.
  --output-file = Optional switch to specify the output file path. Eiter this or
                  "--output-url" must be specified.
  --output-url = Optional switch to specify the output url. Eiter this or
                  "--output-file" must be specified.
  --additional-fields = List of key-value pairs of additional fields to be
                        included in the aggregatable report. Only supports
                        string valued fields.
  --additional-shared-info-fields = List of key-value pairs of additional
                                    fields to be included in the aggregatable
                                    report's shared_info dictionary.
                                    Only supports string valued fields.
  --disable-payload-encryption = Optional switch. If provided, the aggregatable
                                 report's payload(s) will not be encrypted after
                                 serialization.
  --enable-debug-mode = Optional switch. If provided, debug mode is enabled.
                        Otherwise, it is disabled.
  --api-version = Optional switch to specify the API version. Default is "".
  --api = Optional switch to specify the enum string identifying which API
          created the report. Default is "attribution-reporting".
)";

void PrintHelp() {
  LOG(INFO) << kHelpMsg;
}

}  // namespace

int main(int argc, char* argv[]) {
  base::SingleThreadTaskExecutor executor(base::MessagePumpType::IO);
  base::ThreadPoolInstance::CreateAndStartWithDefaultParams(
      "aggregation_service_tool");

  base::CommandLine::Init(argc, argv);
  base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();

  base::CommandLine::StringVector args = command_line.GetArgs();

  if (args.size() != 0U) {
    LOG(ERROR)
        << "aggregation_service_tool does not expect any additional arguments.";
    PrintHelp();
    return 1;
  }

  const std::vector<std::string> kAllowedSwitches = {
      kSwitchHelp,
      kSwitchHelpShort,
      kSwitchOperation,
      kSwitchBucket,
      kSwitchValue,
      kSwitchAlternativeAggregationMode,
      kSwitchReportingOrigin,
      kSwitchHelperKeyUrls,
      kSwitchHelperKeyFiles,
      kSwitchOutputFile,
      kSwitchOutputUrl,
      kSwitchDisablePayloadEncryption,
      kSwitchAdditionalFields,
      kSwitchAdditionalSharedInfoFields,
      kSwitchEnableDebugMode,
      kSwitchApiVersion,
      kSwitchApi};
  for (const auto& provided_switch : command_line.GetSwitches()) {
    if (!base::Contains(kAllowedSwitches, provided_switch.first)) {
      LOG(ERROR) << "aggregation_service_tool did not expect "
                 << provided_switch.first << " to be specified.";
      PrintHelp();
      return 1;
    }
  }

  if (command_line.GetSwitches().empty() ||
      command_line.HasSwitch(kSwitchHelp) ||
      command_line.HasSwitch(kSwitchHelpShort)) {
    PrintHelp();
    return 1;
  }

  const std::vector<std::string> kRequiredSwitches = {
      kSwitchBucket, kSwitchValue, kSwitchReportingOrigin};
  for (const std::string& required_switch : kRequiredSwitches) {
    if (!command_line.HasSwitch(required_switch.c_str())) {
      LOG(ERROR) << "aggregation_service_tool expects " << required_switch
                 << " to be specified.";
      PrintHelp();
      return 1;
    }
  }

  // Either output or reporting url should be specified, but not both.
  if (!(command_line.HasSwitch(kSwitchOutputFile) ^
        command_line.HasSwitch(kSwitchOutputUrl))) {
    LOG(ERROR) << "aggregation_service_tool expects either "
               << kSwitchOutputFile << " or " << kSwitchOutputUrl
               << " to be specified, but not both.";
    PrintHelp();
    return 1;
  }

  // Either helper key URL or file should be specified, but not both.
  if (!(command_line.HasSwitch(kSwitchHelperKeyUrls) ^
        command_line.HasSwitch(kSwitchHelperKeyFiles))) {
    LOG(ERROR) << "aggregation_service_tool expects either "
               << kSwitchHelperKeyUrls << " or " << kSwitchHelperKeyFiles
               << " to be specified, but not both.";
    PrintHelp();
    return 1;
  }

  aggregation_service::AggregationServiceTool tool;

  tool.SetDisablePayloadEncryption(
      /*should_disable=*/command_line.HasSwitch(
          kSwitchDisablePayloadEncryption));

  std::vector<GURL> processing_urls;

  if (command_line.HasSwitch(kSwitchHelperKeyUrls)) {
    std::string switch_value =
        command_line.GetSwitchValueASCII(kSwitchHelperKeyUrls);
    std::vector<std::string> helper_key_url_strings =
        base::SplitString(switch_value, /*separators=*/" ",
                          base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);

    for (const std::string& url_string : helper_key_url_strings) {
      GURL helper_key_url(url_string);
      if (!network::IsUrlPotentiallyTrustworthy(helper_key_url)) {
        LOG(ERROR) << "Helper key URL " << url_string
                   << " is not potentially trustworthy.";
        return 1;
      }
      processing_urls.emplace_back(std::move(helper_key_url));
    }
  } else {
    std::string switch_value =
        command_line.GetSwitchValueASCII(kSwitchHelperKeyFiles);

    std::vector<std::string> helper_key_file_strings =
        base::SplitString(switch_value, /*separators=*/" ",
                          base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);

    if (helper_key_file_strings.empty() || helper_key_file_strings.size() > 2) {
      LOG(ERROR) << kSwitchHelperKeyFiles
                 << " specified an invalid number of files: "
                 << helper_key_file_strings.size();
      return 1;
    }

    std::vector<aggregation_service::UrlKeyFile> key_files;
    for (size_t i = 0; i < helper_key_file_strings.size(); ++i) {
      // We need to choose some URL to store each set of public keys under.
      std::string fake_helper_url =
          base::StringPrintf("https://fake_%zu.example/keys.json", i);
      key_files.emplace_back(GURL(fake_helper_url), helper_key_file_strings[i]);
      processing_urls.emplace_back(std::move(fake_helper_url));
    }

    if (!tool.SetPublicKeys(key_files)) {
      LOG(ERROR) << "aggregation_service_tool failed to set public keys.";
      return 1;
    }
  }

  std::string operation =
      command_line.HasSwitch(kSwitchOperation)
          ? command_line.GetSwitchValueASCII(kSwitchOperation)
          : "histogram";

  std::string aggregation_mode =
      command_line.HasSwitch(kSwitchAlternativeAggregationMode)
          ? command_line.GetSwitchValueASCII(kSwitchAlternativeAggregationMode)
          : "default";

  url::Origin reporting_origin = url::Origin::Create(
      GURL(command_line.GetSwitchValueASCII(kSwitchReportingOrigin)));

  bool is_debug_mode_enabled = command_line.HasSwitch(kSwitchEnableDebugMode);

  base::Value::Dict additional_shared_info_fields;
  if (command_line.HasSwitch(kSwitchAdditionalSharedInfoFields)) {
    std::string additional_shared_info_fields_str =
        command_line.GetSwitchValueASCII(kSwitchAdditionalSharedInfoFields);
    // `additional_shared_info_fields_str` is formatted like
    // "key1=value1,key2=value2".
    base::StringPairs kv_pairs;
    base::SplitStringIntoKeyValuePairs(
        additional_shared_info_fields_str, /*key_value_delimiter=*/'=',
        /*key_value_pair_delimiter=*/',', &kv_pairs);
    for (std::pair<std::string, std::string>& kv : kv_pairs) {
      additional_shared_info_fields.Set(std::move(kv.first),
                                        std::move(kv.second));
    }
  }

  std::string api_version =
      command_line.HasSwitch(kSwitchApiVersion)
          ? command_line.GetSwitchValueASCII(kSwitchApiVersion)
          : "";

  std::string api_identifier =
      command_line.HasSwitch(kSwitchApi)
          ? command_line.GetSwitchValueASCII(kSwitchApi)
          : "attribution-reporting";

  base::Value::Dict report_dict = tool.AssembleReport(
      std::move(operation), command_line.GetSwitchValueASCII(kSwitchBucket),
      command_line.GetSwitchValueASCII(kSwitchValue),
      std::move(aggregation_mode), std::move(reporting_origin),
      std::move(processing_urls), is_debug_mode_enabled,
      std::move(additional_shared_info_fields), std::move(api_version),
      std::move(api_identifier));
  if (report_dict.empty()) {
    LOG(ERROR)
        << "aggregation_service_tool failed to create the aggregatable report.";
    return 1;
  }

  if (command_line.HasSwitch(kSwitchAdditionalFields)) {
    std::string additional_fields =
        command_line.GetSwitchValueASCII(kSwitchAdditionalFields);
    // `additional_fields` is formatted like "key1=value1,key2=value2".
    base::StringPairs kv_pairs;
    base::SplitStringIntoKeyValuePairs(
        additional_fields, /*key_value_delimiter=*/'=',
        /*key_value_pair_delimiter=*/',', &kv_pairs);
    for (std::pair<std::string, std::string>& kv : kv_pairs) {
      report_dict.Set(std::move(kv.first), std::move(kv.second));
    }
  }

  base::Value report_contents(std::move(report_dict));

  bool succeeded = false;
  if (command_line.HasSwitch(kSwitchOutputFile)) {
    base::FilePath output_file =
        command_line.GetSwitchValuePath(kSwitchOutputFile);
    succeeded = tool.WriteReportToFile(report_contents, output_file);

    if (!succeeded) {
      LOG(ERROR) << "aggregation_service_tool failed to write to "
                 << output_file << ".";
    }
  } else {
    std::string output_url = command_line.GetSwitchValueASCII(kSwitchOutputUrl);
    succeeded = tool.SendReport(report_contents, GURL(output_url));

    if (!succeeded) {
      LOG(ERROR) << "aggregation_service_tool failed to send the report to "
                 << output_url << ".";
    }
  }

  if (!succeeded)
    return 1;

  return 0;
}
