// Copyright 2015 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.

// The ARC collector reports crashes that happen in the ARC++ container (android
// on chrome os).
// If a process crashes (not just exits abnormally), the kernel invokes
// crash_reporter via /proc/sys/kernel/core_pattern, which in turn calls the ARC
// collector if the crash happened in that container namespace.

#ifndef CRASH_REPORTER_ARC_COLLECTOR_H_
#define CRASH_REPORTER_ARC_COLLECTOR_H_

#include <memory>
#include <sstream>
#include <string>
#include <unordered_map>

#include <base/macros.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST

#include "crash-reporter/user_collector_base.h"

// Collector for system crashes in the ARC container.
class ArcCollector : public UserCollectorBase {
 public:
  struct Context {
    virtual ~Context() = default;

    virtual bool GetArcPid(pid_t* pid) const = 0;
    virtual bool GetPidNamespace(pid_t pid, std::string* ns) const = 0;
    virtual bool GetExeBaseName(pid_t pid, std::string* exe) const = 0;
    virtual bool GetCommand(pid_t pid, std::string* command) const = 0;
    virtual bool ReadAuxvForProcess(pid_t pid, std::string* contents) const = 0;
  };

  struct BuildProperty {
    std::string device;
    std::string board;
    std::string cpu_abi;
    std::string fingerprint;
  };

  using ContextPtr = std::unique_ptr<Context>;

  ArcCollector();
  explicit ArcCollector(ContextPtr context);
  ~ArcCollector() override = default;

  const Context& context() const { return *context_; }

  // Returns false if the query failed, which may happen during teardown of the
  // ARC container. Since the behavior of user collectors is determined by
  // IsArcProcess, there is a (rare) race condition for crashes that occur
  // during teardown.
  bool IsArcProcess(pid_t pid) const;

  // Reads a Java crash log for the given |crash_type| from standard input, or
  // closes the stream if reporting is disabled.
  bool HandleJavaCrash(const std::string& crash_type,
                       const BuildProperty& build_property);

  static bool IsArcRunning();
  static bool GetArcPid(pid_t* arc_pid);

 private:
  FRIEND_TEST(ArcCollectorTest, CorrectlyDetectBitness);
  FRIEND_TEST(ArcCollectorTest, GetExeBaseNameForUserCrash);
  FRIEND_TEST(ArcCollectorTest, GetExeBaseNameForArcCrash);
  FRIEND_TEST(ArcCollectorTest, ShouldDump);

  // Shift for UID namespace in ARC.
  static constexpr uid_t kUserShift = 655360;

  // Upper bound for system UIDs in ARC.
  static constexpr uid_t kSystemUserEnd = kUserShift + 10000;

  class ArcContext : public Context {
   public:
    explicit ArcContext(ArcCollector* collector) : collector_(collector) {}

    bool GetArcPid(pid_t* pid) const override;
    bool GetPidNamespace(pid_t pid, std::string* ns) const override;
    bool GetExeBaseName(pid_t pid, std::string* exe) const override;
    bool GetCommand(pid_t pid, std::string* command) const override;
    bool ReadAuxvForProcess(pid_t pid, std::string* contents) const override;

   private:
    ArcCollector* const collector_;
  };

  // CrashCollector overrides.
  std::string GetOsVersion() const override;
  bool GetExecutableBaseNameFromPid(pid_t pid, std::string* base_name) override;

  // UserCollectorBase overrides.
  bool ShouldDump(pid_t pid,
                  uid_t uid,
                  const std::string& exec,
                  std::string* reason) override;

  ErrorType ConvertCoreToMinidump(pid_t pid,
                                  const base::FilePath& container_dir,
                                  const base::FilePath& core_path,
                                  const base::FilePath& minidump_path) override;

  // Adds the |process|, |crash_type| and Chrome version as metadata. The
  // |add_arc_properties| option requires privilege to access the ARC root.
  void AddArcMetaData(const std::string& process,
                      const std::string& crash_type,
                      bool add_arc_properties);

  using CrashLogHeaderMap = std::unordered_map<std::string, std::string>;

  bool CreateReportForJavaCrash(const std::string& crash_type,
                                const BuildProperty& build_property,
                                const CrashLogHeaderMap& map,
                                const std::string& exception_info,
                                const std::string& log,
                                bool* out_of_capacity);

  // Returns whether the process identified by |pid| is 32- or 64-bit.
  ErrorType Is64BitProcess(int pid, bool* is_64_bit) const;

  const ContextPtr context_;

  DISALLOW_COPY_AND_ASSIGN(ArcCollector);
};

#endif  // CRASH_REPORTER_ARC_COLLECTOR_H_
