// Copyright 2017 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/bert_collector.h"

#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/logging.h>
#include <brillo/syslog_logging.h>
#include <fcntl.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "crash-reporter/test_util.h"

using base::FilePath;
using brillo::FindLog;

namespace {

constexpr char kACPITableDirectory[] = "sys/firmware/acpi/tables";

bool s_consent_given = true;

bool IsMetrics() {
  return s_consent_given;
}

}  // namespace

class BERTCollectorMock : public BERTCollector {
 public:
  MOCK_METHOD(void, SetUpDBus, (), (override));
};

class BERTCollectorTest : public ::testing::Test {
 protected:
  BERTCollectorMock collector_;
  FilePath test_dir_;
  base::ScopedTempDir scoped_temp_dir_;

  void PrepareBertDataTest(bool good_data) {
    constexpr char data[] = "Create BERT File for testing";
    FilePath testberttable_path = collector_.acpitable_path_.Append("BERT");
    FilePath testbertdata_path = collector_.acpitable_path_.Append("data/BERT");

    ASSERT_TRUE(test_util::CreateFile(testbertdata_path, data));

    if (!good_data) {
      ASSERT_TRUE(test_util::CreateFile(testberttable_path, data));
    } else {
      // Dummy test values.
      const struct acpi_table_bert bert_tab_test = {
          {'B', 'E', 'R', 'T'},
          48,
          'A',
          'D',
          "OEMID",
          "TABLEID",
          0xFFFFFFFF,
          "ACP",
          0xEEEEEEEE,
          sizeof(data),
          0x000000000001234,
      };
      ASSERT_EQ(sizeof(struct acpi_table_bert),
                base::WriteFile(testberttable_path,
                                reinterpret_cast<const char*>(&bert_tab_test),
                                sizeof(struct acpi_table_bert)));
    }
  }

 public:
  void SetUp() override {
    s_consent_given = true;

    EXPECT_CALL(collector_, SetUpDBus()).WillRepeatedly(testing::Return());

    collector_.Initialize(IsMetrics, false);
    ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
    FilePath test_dir_ = scoped_temp_dir_.GetPath();

    collector_.set_crash_directory_for_test(test_dir_);
    collector_.acpitable_path_ = test_dir_.Append(kACPITableDirectory);
  }
};

TEST_F(BERTCollectorTest, TestNoBERTData) {
  ASSERT_FALSE(collector_.Collect());
  EXPECT_EQ(collector_.get_bytes_written(), 0);
}

TEST_F(BERTCollectorTest, TestNoConsent) {
  s_consent_given = false;
  PrepareBertDataTest(false);
  ASSERT_TRUE(collector_.Collect());
  ASSERT_TRUE(FindLog("(ignoring - no consent)"));
  EXPECT_EQ(collector_.get_bytes_written(), 0);
}

TEST_F(BERTCollectorTest, TestBadBERTData) {
  PrepareBertDataTest(false);
  ASSERT_FALSE(collector_.Collect());
  ASSERT_TRUE(FindLog("(handling)"));
  ASSERT_TRUE(FindLog("Bad data in BERT table"));
  EXPECT_EQ(collector_.get_bytes_written(), 0);
}

TEST_F(BERTCollectorTest, TestGoodBERTData) {
  PrepareBertDataTest(true);
  logging::SetMinLogLevel(-3);
  ASSERT_TRUE(collector_.Collect());
  ASSERT_TRUE(FindLog("(handling)"));
  ASSERT_TRUE(FindLog("Stored BERT dump"));
  EXPECT_GT(collector_.get_bytes_written(), 0);
}
