// Copyright (c) 2012 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 DEBUGD_SRC_LOG_TOOL_H_
#define DEBUGD_SRC_LOG_TOOL_H_

#include <sys/types.h>
#include <map>
#include <memory>
#include <set>
#include <string>

#include <base/files/scoped_file.h>
#include <base/macros.h>
#include <base/memory/ref_counted.h>
#include <cryptohome/proto_bindings/rpc.pb.h>
#include <cryptohome-client/cryptohome/dbus-proxies.h>
#include <dbus/bus.h>

#include "debugd/src/sandboxed_process.h"

namespace debugd {

class LogTool {
 public:
  // The encoding for a particular log.
  enum class Encoding {
    // Tries to see if the log output is valid UTF-8. Outputs it as-is if it is,
    // or base64-encodes it otherwise.
    kAutodetect,

    // Replaces any characters that are not valid UTF-8 encoded with the
    // replacement character.
    kUtf8,

    // base64-encodes the output.
    kBase64,

    // Doesn't apply an encoding. Copies the data as is.
    kBinary,
  };

  class Log {
   public:
    enum LogType { kCommand, kFile };

    static constexpr int64_t kDefaultMaxBytes = 512 * 1024;

    Log(LogType type,
        std::string name,
        std::string data,
        std::string user = SandboxedProcess::kDefaultUser,
        std::string group = SandboxedProcess::kDefaultGroup,
        int64_t max_bytes = kDefaultMaxBytes,
        LogTool::Encoding encoding = LogTool::Encoding::kAutodetect,
        bool access_root_mount_ns = false);

    virtual ~Log() = default;

    std::string GetName() const;
    virtual std::string GetLogData() const;

    std::string GetCommandLogData() const;
    std::string GetFileLogData() const;

    void DisableMinijailForTest();

   protected:
    Log() = default;  // For testing only.

   private:
    static uid_t UidForUser(const std::string& name);
    static gid_t GidForGroup(const std::string& group);

    LogType type_;
    std::string name_;
    // For kCommand logs, this is the command to run.
    // For kFile logs, this is the file path to read.
    std::string data_;
    std::string user_;
    std::string group_;
    int64_t max_bytes_;  // passed as arg to 'tail -c'
    LogTool::Encoding encoding_;
    bool access_root_mount_ns_;

    bool minijail_disabled_for_test_ = false;
  };

  explicit LogTool(scoped_refptr<dbus::Bus> bus);

  ~LogTool() = default;

  using LogMap = std::map<std::string, std::string>;

  std::string GetLog(const std::string& name);
  LogMap GetAllLogs();
  LogMap GetAllDebugLogs();
  void GetBigFeedbackLogs(const base::ScopedFD& fd,
                          const std::string& username);
  void BackupArcBugReport(const std::string& userhash);
  void DeleteArcBugReportBackup(const std::string& userhash);
  void GetJournalLog(const base::ScopedFD& fd);

  // Returns a representation of |value| with the specified encoding.
  static std::string EncodeString(std::string value,
                                  Encoding source_encoding);

 private:
  friend class LogToolTest;

  // For testing only.
  LogTool(scoped_refptr<dbus::Bus> bus,
          std::unique_ptr<org::chromium::CryptohomeInterfaceProxyInterface>
              cryptohome_proxy,
          const std::unique_ptr<LogTool::Log> arc_bug_report_log,
          const base::FilePath& daemon_store_base_dir);

  void CreateConnectivityReport(bool wait_for_results);

  // Returns the output of arc-bugreport program in ARC.
  // Returns cached output if it is available for this user.
  std::string GetArcBugReport(const std::string& username, bool* is_backup);
  base::FilePath GetArcBugReportBackupFilePath(const std::string& userhash);

  scoped_refptr<dbus::Bus> bus_;
  std::unique_ptr<org::chromium::CryptohomeInterfaceProxyInterface>
      cryptohome_proxy_;

  std::unique_ptr<LogTool::Log> arc_bug_report_log_;

  base::FilePath daemon_store_base_dir_;
  // Set containing userhash of all users for which
  // ARC bug report has been backed up.
  std::set<std::string> arc_bug_report_backups_;

  DISALLOW_COPY_AND_ASSIGN(LogTool);
};

}  // namespace debugd

#endif  // DEBUGD_SRC_LOG_TOOL_H_
