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

#include "crash-reporter/arcvm_kernel_collector.h"

#include <fcntl.h>
#include <unistd.h>
#include <memory>
#include <utility>

#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/files/scoped_temp_dir.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <gtest/gtest.h>

#include "crash-reporter/test_util.h"

namespace {

constexpr char kTestCrashDirectory[] = "test-crash-directory";
constexpr char kBasenameWithoutExt[] = "arcvm_kernel.20190101.000000.*.0";
constexpr char kExecName[] = "arcvm-kernel";
constexpr time_t kTimestamp = 1546300800;

constexpr char kDevice[] = "Device";
constexpr char kBoard[] = "Board";
constexpr char kCpuAbi[] = "CPUABI";
constexpr char kFingerprint[] = "Fingerprint";

arc_util::BuildProperty GetBuildProperty() {
  return {.device = kDevice,
          .board = kBoard,
          .cpu_abi = kCpuAbi,
          .fingerprint = kFingerprint};
}

constexpr char kRamoopsSampleContent[] =
    "Panic#1 Part1\n"
    "<6>example@google.com shouled be stripped\n"
    "<0>[ 246.088355] Kernel panic - not syncing: sysrq triggered crash\n"
    "<4>[ 246.089203] CPU: 1 PID: 2536 Comm: sh Not tainted "
    "5.4.73-10450-g5f72588ca054 #1\n"
    "<4>[ 246.090349] Hardware name: ChromiumOS crosvm, BIOS 0\n"
    "<4>[ 246.091050] Call Trace:\n"
    "<4>[ 246.091863] dump_stack+0x88/0xcc\n"
    "<4>[ 246.092693] panic+0x100/0x2f1\n"
    "<4>[ 246.093710] sysrq_handle_crash+0x13/0x13\n"
    "<4>[ 246.094467] __handle_sysrq+0x115/0x12f\n"
    "<4>[ 246.095142] write_sysrq_trigger+0x35/0x49\n"
    "<4>[ 246.095852] proc_reg_write+0x37/0x68\n"
    "<4>[ 246.096549] __vfs_write+0x3d/0x199\n"
    "<4>[ 246.097311] ? selinux_file_permission+0x8f/0x124\n"
    "<4>[ 246.098111] vfs_write+0xea/0x192\n"
    "<4>[ 246.098780] ksys_write+0x68/0xc9\n"
    "<4>[ 246.099484] do_syscall_64+0x4b/0x74\n"
    "<4>[ 246.100151] entry_SYSCALL_64_after_hwframe+0x44/0xa9\n"
    "<4>[ 246.101035] RIP: 0033:0x725b4ecba5b7\n"
    "<4>[ 246.101617] Code: 00 00 00 b8 00 00 00 00 0f 05 48 3d 01 f0 ff ff 72 "
    "09 f7 d8 89 c7 e8 08 fb ff ff c3 0f 1f 80 00 00 00 00 b8 01 00 00 00 0f "
    "05 <48> 3d 01 f0 ff ff 72 09 f7 d8 89 c7 e8 e8 fa ff ff c3 0f 1f 80 00\n"
    "<4>[ 246.103266] RSP: 002b:00007fffc5925ed8 EFLAGS: 00000217 ORIG_RAX: "
    "0000000000000001\n"
    "<4>[ 246.104135] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: "
    "0000725b4ecba5b7\n"
    "<4>[ 246.105117] RDX: 0000000000000002 RSI: 00007259beb72018 RDI: "
    "0000000000000001\n"
    "<4>[ 246.105924] RBP: 00007259beb72018 R08: ffffffffffffffff R09: "
    "000072597eb70368\n"
    "<4>[ 246.106966] R10: 00000000fffffe00 R11: 0000000000000217 R12: "
    "0000589b639779c0\n"
    "<4>[ 246.107815] R13: 00007fffc5925ef0 R14: 00007259eeb75af0 R15: "
    "00007fffc5925f28\n"
    "<0>[ 246.109609] Kernel Offset: 0x26a00000 from 0xffffffff81000000 "
    "(relocation range: 0xffffffff80000000-0xffffffffbfffffff)\n";

constexpr char kKeywordinRamoops[] =
    "Kernel panic - not syncing: sysrq triggered crash";
constexpr char kSensitiveDataInRamoops[] = "example@google.com";

}  // namespace

class TestArcvmKernelCollector : public ArcvmKernelCollector {
 public:
  explicit TestArcvmKernelCollector(const base::FilePath& crash_directory) {
    Initialize(false /* early */);
    set_crash_directory_for_test(crash_directory);
  }
  ~TestArcvmKernelCollector() override = default;

  bool HasMetaData(const std::string& key, const std::string& value) const {
    const std::string metadata =
        base::StringPrintf("%s=%s\n", key.c_str(), value.c_str());
    return extra_metadata_.find(metadata) != std::string::npos;
  }

 private:
  void SetUpDBus() override {}
};

class ArcvmKernelCollectorTest : public ::testing::Test {
 public:
  ~ArcvmKernelCollectorTest() override = default;

  void SetUp() override {
    ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());

    base::FilePath ramoops_path =
        scoped_temp_dir_.GetPath().Append("dmesg-ramoops-0");
    ASSERT_TRUE(test_util::CreateFile(ramoops_path, kRamoopsSampleContent));
    ramoops_stream_ =
        base::ScopedFILE(fopen(ramoops_path.value().c_str(), "r"));
    ASSERT_TRUE(ramoops_stream_);

    test_crash_directory_ =
        scoped_temp_dir_.GetPath().Append(kTestCrashDirectory);
    ASSERT_TRUE(base::CreateDirectory(test_crash_directory_));
    collector_ =
        std::make_unique<TestArcvmKernelCollector>(test_crash_directory_);
  }

 protected:
  base::ScopedTempDir scoped_temp_dir_;
  base::ScopedFILE ramoops_stream_;
  base::FilePath test_crash_directory_;
  std::unique_ptr<TestArcvmKernelCollector> collector_;
};

TEST_F(ArcvmKernelCollectorTest, HandleCrashWithRamoopsStreamAndTimestamp) {
  ASSERT_TRUE(collector_->HandleCrashWithRamoopsStreamAndTimestamp(
      GetBuildProperty(), ramoops_stream_.get(), kTimestamp));

  EXPECT_TRUE(test_util::DirectoryHasFileWithPattern(
      test_crash_directory_, std::string(kBasenameWithoutExt) + ".meta",
      nullptr));

  base::FilePath ramoops_path;
  ASSERT_TRUE(test_util::DirectoryHasFileWithPattern(
      test_crash_directory_, std::string(kBasenameWithoutExt) + ".log",
      &ramoops_path));
  std::string ramoops_content;
  EXPECT_TRUE(base::ReadFileToString(ramoops_path, &ramoops_content));
  EXPECT_THAT(ramoops_content, testing::HasSubstr(kKeywordinRamoops));
  EXPECT_THAT(ramoops_content,
              testing::Not(testing::HasSubstr(kSensitiveDataInRamoops)));
}

TEST_F(ArcvmKernelCollectorTest, AddArcMetadata) {
  collector_->AddArcMetadata(GetBuildProperty());
  EXPECT_TRUE(collector_->HasMetaData(arc_util::kProcessField, kExecName));
  EXPECT_TRUE(
      collector_->HasMetaData(arc_util::kProductField, arc_util::kArcProduct));
  EXPECT_TRUE(
      collector_->HasMetaData(arc_util::kArcVersionField, kFingerprint));
  EXPECT_TRUE(collector_->HasMetaData(arc_util::kDeviceField, kDevice));
  EXPECT_TRUE(collector_->HasMetaData(arc_util::kBoardField, kBoard));
  EXPECT_TRUE(collector_->HasMetaData(arc_util::kCpuAbiField, kCpuAbi));
}
