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

#ifndef CRASH_REPORTER_CRASH_SENDER_UTIL_H_
#define CRASH_REPORTER_CRASH_SENDER_UTIL_H_

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/files/file.h>
#include <base/files/file_path.h>
#include <base/optional.h>
#include <base/time/clock.h>
#include <base/time/time.h>
#include <base/values.h>
#include <brillo/http/http_form_data.h>
#include <brillo/http/http_transport.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST
#include <metrics/metrics_library.h>
#include <session_manager/dbus-proxies.h>
#include <shill/dbus-proxies.h>

#include "crash-reporter/crash_sender_base.h"

namespace util {

// URL to send official build crash reports to.
constexpr char kReportUploadProdUrl[] = "https://clients2.google.com/cr/report";

// URL to send test/dev build crash reports to.
constexpr char kReportUploadStagingUrl[] =
    "https://clients2.google.com/cr/staging_report";

// Maximum crashes to send per 24 hours.
constexpr int kMaxCrashRate = 32;

// Maximum bytes of crash reports to send per 24 hours. Note that "whichever
// comes last" maximum with kMaxCrashRate; that is, we'll always send 32 crashes
// per 24 hours, even if that exceeds 24MB, and we'll always send 24MB per 24
// hours, even if that exceeds 32 crashes.
constexpr int kMaxCrashBytes = 24 * 1024 * 1024;

// Maximum time to sleep before attempting to send a crash report. This value is
// inclusive as an upper bound, thus 0 means a crash report can be sent
// immediately.
constexpr int kMaxSpreadTimeInSeconds = 600;

// Parsed command line flags.
struct CommandLineFlags {
  base::TimeDelta max_spread_time;
  std::string crash_directory;
  bool ignore_rate_limits = false;
  bool ignore_hold_off_time = false;
  bool allow_dev_sending = false;
  bool ignore_pause_file = false;
  bool test_mode = false;
  bool upload_old_reports = false;
};

// Represents a metadata file name, and its parsed metadata.
typedef std::pair<base::FilePath, CrashInfo> MetaFile;

// Parses the command line, and handles the command line flags.
//
// On error, the process exits as a failure with an error message for the
// first-encountered error.
void ParseCommandLine(int argc,
                      const char* const* argv,
                      CommandLineFlags* flags);

// Returns true if the marker file exists indicating we should pause sending.
// This can be overridden with a command line flag to the program.
bool DoesPauseFileExist();

// Gets the base part of a crash report file, such as:
// name.01234.5678.9012.meta -> name.01234.5678.9012
// name.01234.5678.1234.9012.meta -> name.01234.5678.1234.9012
// name.01234.5678.9012.log.tar.xz -> name.01234.5678.9012
// name.01234.5678.1234.9012.log.tar.xz -> name.01234.5678.1234.9012
// This supports both 4-segment and 5-segment basenames, as long as the last
// segment always is numeric and the extension does not start with an
// all-numeric component.
//
// We make sure "name" is sanitized in CrashCollector::Sanitize to not include
// any periods. The directory part will be preserved.
base::FilePath GetBasePartOfCrashFile(const base::FilePath& file_name);

// Removes orphaned files in |crash_dir|, that are files 24 hours old or older,
// without corresponding meta file.
void RemoveOrphanedCrashFiles(const base::FilePath& crash_dir);

// Sort the vector of crash reports so that the report we want to send first
// is at the front of the vector.
void SortReports(std::vector<MetaFile>* reports);

// Returns the list of meta data files (files with ".meta" suffix), sorted by
// the timestamp in the old-to-new order.
std::vector<base::FilePath> GetMetaFiles(const base::FilePath& crash_dir);

// Returns true if the metadata indicates that the crash was already uploaded.
bool IsAlreadyUploaded(const base::FilePath& meta_file);

// Returns true if the given timestamp file is new enough, indicating that there
// was a recent attempt to send a crash report.
bool IsTimestampNewEnough(const base::FilePath& timestamp_file);

// Returns true if sending a crash report now does not exceed |max_crash_rate|
// crashes and |max_crash_bytes| bytes per 24 hours.
//
// |timestamps_dir| contains the state files indicating how many sends have
// happened and how big they were.
bool IsBelowRate(const base::FilePath& timestamps_dir,
                 int max_crash_rate,
                 int max_crash_bytes);

// Records a crash send attempt so that IsBelowRate knows about it.
// |timestamps_dir| should be the same directory passed to IsBelowRate().
// |bytes| is the number of bytes sent over the network.
void RecordSendAttempt(const base::FilePath& timestamps_dir, int bytes);

// A helper class for sending crashes. The behaviors can be customized with
// Options class for unit testing.
//
// Crash reports will be sent even when the device is on a mobile data
// connection (see crbug.com/185110 for discussion).
class Sender : public SenderBase {
 public:
  struct Options : SenderBase::Options {
    // Shill FlimFlam Manager proxy interface for determining network state.
    org::chromium::flimflam::ManagerProxyInterface* shill_proxy = nullptr;

    // Maximum crashes to send per 24 hours. (We'll send more if still below
    // max_crash_bytes.)
    int max_crash_rate = kMaxCrashRate;

    // Maximum bytes we will upload per 24 hours. (We'll send more if still
    // below max_crash_rate.)
    int max_crash_bytes = kMaxCrashBytes;

    // Maximum time to sleep before attempting to send.
    base::TimeDelta max_spread_time;

    // Boundary to use in the form data.
    std::string form_data_boundary;

    // If true, we will ignore other checks when deciding if we should write to
    // the Chrome uploads.log file.
    bool always_write_uploads_log = false;

    // If true, we allow sending crash reports for unofficial test images and
    // the reports are uploaded to a staging crash server instead.
    bool allow_dev_sending = false;

    // If true, just log the kTestModeSuccessful message if the crash report
    // looks legible instead of actually uploading it.
    bool test_mode = false;

    // If true, ignore timestamp check and upload old reports.
    bool upload_old_reports = false;
  };

  Sender(std::unique_ptr<MetricsLibraryInterface> metrics_lib,
         std::unique_ptr<base::Clock> clock,
         const Options& options);
  Sender(const Sender&) = delete;
  Sender& operator=(const Sender&) = delete;

  // Chooses an action to take for the crash report associated with the given
  // meta file, and reports the reason. The crash information will be stored in
  // |info| for reuse.
  SenderBase::Action ChooseAction(const base::FilePath& meta_file,
                                  std::string* reason,
                                  CrashInfo* info);

  // Removes invalid files in |crash_dir|, that are unknown, corrupted, or
  // invalid in other ways, and picks crash reports that should be sent to the
  // server. The meta files of the latter will be stored in |to_send|.
  void RemoveAndPickCrashFiles(const base::FilePath& directory,
                               std::vector<MetaFile>* reports_to_send);

  // Creates an Http transport object for invoking the Crash Server.
  virtual std::shared_ptr<brillo::http::Transport> GetTransport();

  // Sends each crash in |crash_meta_files|, in multiple steps:
  //
  // For each meta file:
  // - Sleeps to avoid overloading the network
  // - Checks if the device enters guest mode, and stops if entered.
  // - Enforces the rate limit per 24 hours.
  // - Removes crash files that are successfully uploaded.
  void SendCrashes(const std::vector<MetaFile>& crash_meta_files);

  // Given the |details| for a crash, creates a brillo::http::FormData object
  // which will have all of the fields for submission to the crash server
  // populated. Returns a nullptr if there were critical errors in populating
  // the data. This also logs out all of the details during the process. On
  // success, |product_name_out| is also set to the product name (it's not
  // possible to extract data from the returned FormData object in a
  // non-destructive manner).
  std::unique_ptr<brillo::http::FormData> CreateCrashFormData(
      const CrashDetails& details, std::string* product_name_out);

 private:
  friend class IsNetworkOnlineTest;
  FRIEND_TEST(CrashSenderUtilTest, RemoveReportFiles);
  FRIEND_TEST(CrashSenderUtilTest, FailRemoveReportFilesSendsMetric);

  // Removes report files associated with the given meta file.
  // More specifically, if "foo.meta" is given, "foo.*" will be removed.
  void RemoveReportFiles(const base::FilePath& meta_file);

  // Send the specified reason for removing a crash to UMA.
  void RecordCrashRemoveReason(SenderBase::CrashRemoveReason reason) override;

  // Creates a JSON entity with the required fields for uploads.log file.
  std::unique_ptr<base::Value> CreateJsonEntity(const std::string& report_id,
                                                const std::string& product_name,
                                                const CrashDetails& details);

  // Requests to send a crash report represented with the given crash details.
  // If the return code is kRetryUploading, the failure can be retried and the
  // caller should not remove the crash report. Otherwise, the caller should
  // remove the crash report using the returned removal reason code.
  SenderBase::CrashRemoveReason RequestToSendCrash(const CrashDetails& details);

  // Returns true if we have consent to send crashes to Google.
  bool HasCrashUploadingConsent();

  // Is this a "safe" device coredump, from an allowlist of driver names
  // for devices whose device coredump does not contain PII?
  bool IsSafeDeviceCoredump(const CrashInfo& info);

  // Checks if we have an online connection state so we can try sending crash
  // reports.
  bool IsNetworkOnline();

  std::unique_ptr<MetricsLibraryInterface> metrics_lib_;
  std::unique_ptr<org::chromium::flimflam::ManagerProxyInterface> shill_proxy_;
  std::vector<std::string> proxy_servers_;
  std::string form_data_boundary_;
  bool always_write_uploads_log_;
  const int max_crash_rate_;
  const int max_crash_bytes_;
  const base::TimeDelta max_spread_time_;
  bool allow_dev_sending_;
  const bool test_mode_;
  const bool upload_old_reports_;
};

}  // namespace util

#endif  // CRASH_REPORTER_CRASH_SENDER_UTIL_H_
