/* Copyright 2019 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 <memory>
#include <sstream>
#include <utility>

#include <google/protobuf/util/message_differencer.h>
#include <gtest/gtest.h>
#include <metrics/metrics_library_mock.h>
#include <runtime_probe/proto_bindings/runtime_probe.pb.h>

#include "hardware_verifier/cli.h"
#include "hardware_verifier/hardware_verifier.pb.h"
#include "hardware_verifier/hw_verification_report_getter.h"
#include "hardware_verifier/mock_hw_verification_report_getter.h"
#include "hardware_verifier/observer.h"
#include "hardware_verifier/test_utils.h"

namespace hardware_verifier {

namespace {

using ::testing::_;
using ::testing::AtLeast;
using ::testing::DoAll;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SetArgPointee;

using ReportGetterErrorCode = HwVerificationReportGetter::ErrorCode;

class CLIForTesting : public CLI {
 public:
  CLIForTesting(std::unique_ptr<HwVerificationReportGetter> vr_getter,
                std::ostream* output_stream)
      : CLI(std::move(vr_getter), output_stream) {}
};

class CLITest : public testing::Test {
 protected:
  void SetUp() override {
    auto mock_vr_getter =
        std::make_unique<NiceMock<MockHwVerificationReportGetter>>();
    auto mock_metrics = std::make_unique<NiceMock<MetricsLibraryMock>>();
    mock_vr_getter_ = mock_vr_getter.get();
    output_stream_.reset(new std::ostringstream());
    mock_metrics_ = mock_metrics.get();

    cli_.reset(
        new CLIForTesting(std::move(mock_vr_getter), output_stream_.get()));
    Observer::GetInstance()->SetMetricsLibrary(std::move(mock_metrics));

    // Set everything works by default.
    HwVerificationReport vr;
    vr.set_is_compliant(true);
    ON_CALL(*mock_vr_getter_, Get(_, _, _))
        .WillByDefault(
            DoAll(SetArgPointee<2>(ReportGetterErrorCode::kErrorCodeNoError),
                  Return(vr)));
  }

  void TearDown() override {
    // We have to clear the MetricsLibraryMock manually, because
    // Observer::GetInstance() object is a singleton, which won't be destroyed
    // across the tests.
    Observer::GetInstance()->SetMetricsLibrary(nullptr);
  }

  MockHwVerificationReportGetter* mock_vr_getter_;
  std::unique_ptr<std::ostringstream> output_stream_;
  MetricsLibraryMock* mock_metrics_;

  // The object to be tested.
  std::unique_ptr<CLIForTesting> cli_;
};

TEST_F(CLITest, TestOutput) {
  HwVerificationReport vr;
  vr.set_is_compliant(true);
  ON_CALL(*mock_vr_getter_, Get(_, _, _))
      .WillByDefault(
          DoAll(SetArgPointee<2>(ReportGetterErrorCode::kErrorCodeNoError),
                Return(vr)));

  EXPECT_EQ(cli_->Run("", "", CLIOutputFormat::kProtoBin, true),
            CLIVerificationResult::kPass);
  HwVerificationReport result;
  EXPECT_TRUE(result.ParseFromString(output_stream_->str()));
  EXPECT_TRUE(google::protobuf::util::MessageDifferencer::Equals(result, vr));

  // For human readable format, only check if there's something printed.
  *output_stream_ = std::ostringstream();
  EXPECT_EQ(cli_->Run("", "", CLIOutputFormat::kText, false),
            CLIVerificationResult::kPass);
  EXPECT_FALSE(output_stream_->str().empty());

  *output_stream_ = std::ostringstream();
  EXPECT_EQ(cli_->Run("", "", CLIOutputFormat::kText, true),
            CLIVerificationResult::kPass);
  EXPECT_FALSE(output_stream_->str().empty());
}

TEST_F(CLITest, TestGetReportFailed) {
  ON_CALL(*mock_vr_getter_, Get(_, _, _))
      .WillByDefault(
          DoAll(SetArgPointee<2>(ReportGetterErrorCode::kErrorCodeProbeFail),
                Return(base::nullopt)));

  EXPECT_EQ(cli_->Run("", "", CLIOutputFormat::kProtoBin, true),
            CLIVerificationResult::kProbeFail);
}

TEST_F(CLITest, TestMissingPayloads) {
  ON_CALL(*mock_vr_getter_, Get(_, _, _))
      .WillByDefault(DoAll(
          SetArgPointee<2>(ReportGetterErrorCode::
                               kErrorCodeMissingDefaultHwVerificationSpecFile),
          Return(base::nullopt)));

  EXPECT_EQ(cli_->Run("", "", CLIOutputFormat::kProtoBin, true),
            CLIVerificationResult::kSkippedVerification);
}

TEST_F(CLITest, TestVerifyReportSample1) {
  const auto& path = GetTestDataPath()
                         .Append("verifier_impl_sample_data")
                         .Append("expect_hw_verification_report_1.prototxt");
  const auto& vr = LoadHwVerificationReport(path);
  ON_CALL(*mock_vr_getter_, Get(_, _, _))
      .WillByDefault(
          DoAll(SetArgPointee<2>(ReportGetterErrorCode::kErrorCodeNoError),
                Return(vr)));

  // This is for recording running time.
  EXPECT_CALL(
      *mock_metrics_,
      SendBoolToUMA("ChromeOS.HardwareVerifier.Report.IsCompliant", true));
  // This is for recording qualification status of each components.
  EXPECT_CALL(*mock_metrics_, SendEnumToUMA(_, _, _)).Times(AtLeast(3));

  EXPECT_EQ(cli_->Run("", "", CLIOutputFormat::kText, false),
            CLIVerificationResult::kPass);
}

TEST_F(CLITest, TestVerifyReportSample2) {
  const auto& path = GetTestDataPath()
                         .Append("verifier_impl_sample_data")
                         .Append("expect_hw_verification_report_2.prototxt");
  const auto& vr = LoadHwVerificationReport(path);
  ON_CALL(*mock_vr_getter_, Get(_, _, _))
      .WillByDefault(
          DoAll(SetArgPointee<2>(ReportGetterErrorCode::kErrorCodeNoError),
                Return(vr)));

  // This is for recording running time.
  EXPECT_CALL(
      *mock_metrics_,
      SendBoolToUMA("ChromeOS.HardwareVerifier.Report.IsCompliant", false));
  // This is for recording qualification status of each components.
  EXPECT_CALL(*mock_metrics_, SendEnumToUMA(_, _, _)).Times(AtLeast(2));

  EXPECT_EQ(cli_->Run("", "", CLIOutputFormat::kText, false),
            CLIVerificationResult::kFail);
}

}  // namespace

}  // namespace hardware_verifier
