// 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/missed_crash_collector.h"

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/files/scoped_temp_dir.h>
#include <base/strings/strcat.h>
#include <base/strings/string_number_conversions.h>
#include <gtest/gtest.h>

#include "crash-reporter/test_util.h"

using ::testing::HasSubstr;
using ::testing::Return;

namespace {

class MissedCrashCollectorMock : public MissedCrashCollector {
 public:
  MissedCrashCollectorMock() : MissedCrashCollector() {}
  MOCK_METHOD(void, SetUpDBus, (), (override));
};

void RunTestWithLogContents(base::StringPiece log_contents) {
  base::ScopedTempDir tmp_dir;
  ASSERT_TRUE(tmp_dir.CreateUniqueTempDir());

  base::FilePath input = tmp_dir.GetPath().Append("input.txt");
  base::WriteFile(input, log_contents.data(), log_contents.length());

  base::ScopedFILE input_file(fopen(input.value().c_str(), "r"));
  ASSERT_TRUE(input_file.get());

  MissedCrashCollectorMock collector;
  EXPECT_CALL(collector, SetUpDBus()).WillRepeatedly(Return());
  collector.set_crash_directory_for_test(tmp_dir.GetPath());
  collector.set_input_file_for_testing(input_file.get());
  collector.Initialize(false /*early*/);
  constexpr int kPid = 234;
  constexpr int kRecentMissCount = 5;
  constexpr int kRecentMatchCount = 2;
  constexpr int kPendingMissCount = 4;
  EXPECT_TRUE(collector.Collect(kPid, kRecentMissCount, kRecentMatchCount,
                                kPendingMissCount));

  base::FilePath meta_path;
  EXPECT_TRUE(test_util::DirectoryHasFileWithPattern(
      tmp_dir.GetPath(), "missed_crash.*.234.meta", &meta_path));
  base::FilePath log_path;
  EXPECT_TRUE(test_util::DirectoryHasFileWithPattern(
      tmp_dir.GetPath(), "missed_crash.*.234.log.gz", &log_path));

  // Check log contents.
  int decompress_result = system(("gunzip " + log_path.value()).c_str());
  EXPECT_TRUE(WIFEXITED(decompress_result));
  EXPECT_EQ(WEXITSTATUS(decompress_result), 0);
  std::string actual_log_contents;
  EXPECT_TRUE(base::ReadFileToString(log_path.RemoveFinalExtension(),
                                     &actual_log_contents));
  EXPECT_EQ(log_contents, actual_log_contents);

  // Check meta contents.
  std::string meta_contents;
  EXPECT_TRUE(base::ReadFileToString(meta_path, &meta_contents));
  EXPECT_THAT(
      meta_contents,
      HasSubstr(base::StrCat({"payload=", log_path.BaseName().value()})));
  EXPECT_THAT(meta_contents, HasSubstr("sig=missed-crash"));
  EXPECT_THAT(meta_contents, HasSubstr("upload_var_recent_miss_count=5"));
  EXPECT_THAT(meta_contents, HasSubstr("upload_var_recent_match_count=2"));
  EXPECT_THAT(meta_contents, HasSubstr("upload_var_pending_miss_count=4"));
  EXPECT_THAT(meta_contents, HasSubstr("upload_var_pid=234"));
  EXPECT_THAT(meta_contents, HasSubstr("done=1"));
}

}  // namespace

TEST(MissedCrashCollectorTest, Basic) {
  constexpr char kInput[] = R"(===stuff===
1 2 3
===more stuff===
hello
)";
  RunTestWithLogContents(kInput);
}

// Ensure our private ReadFILEToString handles files larger than
// kDefaultChunkSize correctly.
TEST(MissedCrashCollectorTest, LargeInput) {
  std::string contents;
  for (int i = 0; i < MissedCrashCollector::kDefaultChunkSize; ++i) {
    base::StrAppend(&contents, {base::NumberToString(i), "|"});
  }
  // Make sure this doesn't overlap with the ExactMultiple test below.
  ASSERT_NE(contents.size() % MissedCrashCollector::kDefaultChunkSize, 0);
  ASSERT_NE(contents.size() % MissedCrashCollector::kDefaultChunkSize, 1);
  ASSERT_NE(contents.size() % MissedCrashCollector::kDefaultChunkSize,
            MissedCrashCollector::kDefaultChunkSize - 1);
  RunTestWithLogContents(contents);
}

// Ensure our private ReadFILEToString handles files exactly equal to
// kDefaultChunkSize in size.
TEST(MissedCrashCollectorTest, OneChunk) {
  std::string contents;
  for (int i = 0; i < MissedCrashCollector::kDefaultChunkSize; ++i) {
    base::StrAppend(&contents, {base::NumberToString(i), "|"});
  }
  contents.resize(MissedCrashCollector::kDefaultChunkSize);
  RunTestWithLogContents(contents);
}

// Ensure our private ReadFILEToString handles files whose size is a multiple of
// kDefaultChunkSize.
TEST(MissedCrashCollectorTest, ExactMultiple) {
  std::string contents;
  for (int i = 0; i < 3 * MissedCrashCollector::kDefaultChunkSize; ++i) {
    base::StrAppend(&contents, {base::NumberToString(i), "|"});
  }
  contents.resize(3 * MissedCrashCollector::kDefaultChunkSize);
  RunTestWithLogContents(contents);
}

// Ensure our private ReadFILEToString handles files whose size is a 1 less
// than a multiple of kDefaultChunkSize.
TEST(MissedCrashCollectorTest, ExactMultipleLessOne) {
  std::string contents;
  for (int i = 0; i < 3 * MissedCrashCollector::kDefaultChunkSize; ++i) {
    base::StrAppend(&contents, {base::NumberToString(i), "|"});
  }
  contents.resize(3 * MissedCrashCollector::kDefaultChunkSize - 1);
  RunTestWithLogContents(contents);
}

// Ensure our private ReadFILEToString handles files whose size is a 1 greater
// than a multiple of kDefaultChunkSize.
TEST(MissedCrashCollectorTest, ExactMultiplePlusOne) {
  std::string contents;
  for (int i = 0; i < 3 * MissedCrashCollector::kDefaultChunkSize; ++i) {
    base::StrAppend(&contents, {base::NumberToString(i), "|"});
  }
  contents.resize(3 * MissedCrashCollector::kDefaultChunkSize + 1);
  RunTestWithLogContents(contents);
}
