// Copyright 2020 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_BASE_H_
#define CRASH_REPORTER_CRASH_SENDER_BASE_H_

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

#include <base/callback.h>
#include <base/files/file.h>
#include <base/files/file_path.h>
#include <base/time/clock.h>
#include <base/time/time.h>
#include <brillo/key_value_store.h>
#include <brillo/osrelease_reader.h>
#include <session_manager/dbus-proxies.h>

namespace util {

// Maximum time to wait for ensuring a meta file is complete.
constexpr base::TimeDelta kMaxHoldOffTime = base::TimeDelta::FromSeconds(30);
constexpr char kUndefined[] = "undefined";
constexpr char kChromeOsProduct[] = "ChromeOS";

// Crash information obtained in ChooseAction().
struct CrashInfo {
  brillo::KeyValueStore metadata;
  base::FilePath payload_file;
  std::string payload_kind;
  // Last modification time of the associated .meta file
  base::Time last_modified;
};

// Details of a crash report. Contains more information than CrashInfo, as
// additional information is extracted at a stage later stage.
struct CrashDetails {
  base::FilePath meta_file;
  base::FilePath payload_file;
  std::string payload_kind;
  std::string client_id;
  const brillo::KeyValueStore& metadata;
};

// Struct representing a fully-read-in meta file. Contains all fields that will
// be sent in crash report, with upload_file_ files and the payload left as
// FilePaths.
struct FullCrash {
  // Name of exec that crashed.
  std::string exec_name;
  // Board (e.g. "eve") of device
  std::string board;
  // Hardware class
  std::string hwclass;
  // product -- named this way to match name crash server expects
  std::string prod;
  // version -- named this way to match name crash server expects
  std::string ver;
  // Signature -- named this way to match name crash server expects
  std::string sig;
  // image type e.g. ("dev", "test", "")
  std::string image_type;
  // boot mode (e.g. "dev" or "")
  std::string boot_mode;
  // Error type (arbitrary, specified by client)
  std::string error_type;
  // client ID of machine
  std::string guid;
  // Payload of the crash. If this cannot be added, report should fail.
  std::pair<std::string, base::FilePath> payload;
  // Arbitrary human-readable key-value pairs.
  std::vector<std::pair<std::string, std::string>> key_vals;
  // Non-payload files to upload (possibly non-human-readable contents). If
  // attaching a non-payload file fails, log an error but continue.
  std::vector<std::pair<std::string, base::FilePath>> files;
};

// Testing hook. Set to true to force IsMock() to always return true. Easier
// than creating the mock file in internal tests (such as fuzz tests).
extern bool g_force_is_mock;

// Testing hook. Set to true to force IsMockSuccessful() to always return true.
// Easier than creating the mock file in internal tests (such as fuzz tests).
extern bool g_force_is_mock_successful;

// Gets the base name of the path pointed by |key| in the given metadata.
// Returns an empty path if the key is not found.
base::FilePath GetBaseNameFromMetadata(const brillo::KeyValueStore& metadata,
                                       const std::string& key);

// Returns which kind of report from the given payload path. Returns an empty
// string if the kind is unknown.
std::string GetKindFromPayloadPath(const base::FilePath& payload_path);

// Parses |raw_metadata| into |metadata|. Keys in metadata are validated (keys
// should consist of expected characters). Returns true on success.
// The original contents of |metadata| will be lost.
bool ParseMetadata(const std::string& raw_metadata,
                   brillo::KeyValueStore* metadata);

// Returns true if the metadata is complete.
bool IsCompleteMetadata(const brillo::KeyValueStore& metadata);

// Records that the crash sending is done.
void RecordCrashDone();

// Returns true if mock is enabled.
bool IsMock();

// Returns true if mock is enabled and we should succeed.
bool IsMockSuccessful();

// Returns the string that describes the type of image. Returns an empty string
// if we shouldn't specify the image type.
std::string GetImageType();

// Computes a sleep time needed before attempting to send a new crash report.
// On success, returns true and stores the result in |sleep_time|. On error,
// returns false.
bool GetSleepTime(const base::FilePath& meta_file,
                  const base::TimeDelta& max_spread_time,
                  const base::TimeDelta& hold_off_time,
                  base::TimeDelta* sleep_time);

// Gets the client ID if it exists, otherwise it generates it, saves it and
// returns that new ID. If it is unable to create the directory for storage, the
// empty string is returned.
std::string GetClientId();

// This class assists us in recovering from crashes while processing crashes.
// When it is constructed, it attempts to create a ".processing" file for the
// given metadata file, and when it is destructed it removes it.
// If crash_sender crashes, or otherwise exits without running the destructor,
// the .processing file will still exist. ChooseAction uses the existence of
// this file to determine that the crash may be malformed and avoid processing
// it again.
class ScopedProcessingFile {
 public:
  explicit ScopedProcessingFile(const base::FilePath& meta_file);

  // Disallow copy and assign (and implicitly, move).
  ScopedProcessingFile(const ScopedProcessingFile& other) = delete;
  ScopedProcessingFile& operator=(const ScopedProcessingFile& other) = delete;

  ~ScopedProcessingFile();

 private:
  const base::FilePath processing_file_;
};

// Base class for crash reading functionality. Used by both crash sender and
// crash serializer.
class SenderBase {
 public:
  struct Options {
    // Session manager client for locating the user-specific crash directories.
    org::chromium::SessionManagerInterfaceProxyInterface*
        session_manager_proxy = nullptr;

    // Do not send the crash report until the meta file is at least this old.
    // This avoids problems with crash reports being sent out while they are
    // still being written.
    base::TimeDelta hold_off_time = kMaxHoldOffTime;

    // Alternate sleep function for unit testing.
    base::Callback<void(base::TimeDelta)> sleep_function;
  };

  SenderBase(std::unique_ptr<base::Clock> clock, const Options& options);

  virtual ~SenderBase() = default;

  // Actions returned by ChooseAction().
  enum Action {
    kRemove,  // Should remove the crash report.
    kIgnore,  // Should ignore (keep) the crash report.
    kSend,    // Should send the crash report.
  };

  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused
  enum CrashRemoveReason {
    kTotalRemoval = 0,
    kNotOfficialImage = 1,
    kNoMetricsConsent = 2,
    kProcessingFileExists = 3,
    kLargeMetaFile = 4,
    kUnparseableMetaFile = 5,
    kPayloadUnspecified = 6,
    kPayloadAbsolute = 7,
    kPayloadNonexistent = 8,
    kPayloadKindUnknown = 9,
    kOSVersionTooOld = 10,
    kOldIncompleteMeta = 11,
    kFinishedUploading = 12,
    kAlreadyUploaded = 13,
    // Keep kSendReasonCount one larger than any other enum value.
    kSendReasonCount = 14,
  };

  // Lock the lock file so no concurrently running process can access the
  // disk files. Dies if lock file cannot be acquired after a delay.
  //
  // Returns the File object holding the lock.
  base::File AcquireLockFileOrDie();

  // Get a list of all directories that might hold user-specific crashes.
  std::vector<base::FilePath> GetUserCrashDirectories();

  // For tests only, crash while sending crashes.
  void SetCrashDuringSendForTesting(bool crash) {
    crash_during_testing_ = crash;
  }

 protected:
  // Do a minimal evaluation of the given meta file, only performing basic
  // validation (e.g. that it's fully written, that the payload field is valid,
  // etc).
  // In particular, this does _not_ check metrics consent, guest mode, or
  // whether the crash is already uploaded.
  // Arguments:
  //  |meta_file| - The path to the metadata file to process.
  //  |allow_old_os_timestamps| - True iff we should return kSend for metadata
  //                              files created on old (>6 mo) OS versions
  //  |reason| - output parameter. Human-readable description of the reason for
  //             the given action. useful for logs.
  //  |info| - output parameter. CrashInfo struct created while evaluating meta
  //           file.
  //  |processing_file| - optional output parameter. If non-null, a
  //                      ScopedProcessingFile will be placed into it.
  //                      This file should remain in scope during all
  //                      additional processing of the meta file.
  Action EvaluateMetaFileMinimal(
      const base::FilePath& meta_file,
      bool allow_old_os_timestamps,
      std::string* reason,
      CrashInfo* info,
      std::unique_ptr<ScopedProcessingFile>* processing_file);

  // Record the reason for removing a crash.
  virtual void RecordCrashRemoveReason(CrashRemoveReason reason) = 0;

  // Makes sure we have the DBus object initialized and connected.
  void EnsureDBusIsReady();

  // Read the meta file and return a struct representing its contents.
  FullCrash ReadMetaFile(const CrashDetails& details);

  // These are accessed by child classes.
  base::Callback<void(base::TimeDelta)> sleep_function_;
  scoped_refptr<dbus::Bus> bus_;
  bool crash_during_testing_ = false;
  const base::TimeDelta hold_off_time_;

 private:
  // Looks through |keys| in the os-release data using brillo::OsReleaseReader.
  // Keys are searched in order until a value is found. Returns the value in
  // the Optional if found, otherwise the Optional is empty.
  base::Optional<std::string> GetOsReleaseValue(
      const std::vector<std::string>& keys);

  std::unique_ptr<base::Clock> clock_;
  std::unique_ptr<org::chromium::SessionManagerInterfaceProxyInterface>
      session_manager_proxy_;
  std::unique_ptr<brillo::OsReleaseReader> os_release_reader_;
};

}  // namespace util

#endif  // CRASH_REPORTER_CRASH_SENDER_BASE_H_
