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

#include <base/bind.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "trunks/mock_command_transceiver.h"
#include "trunks/trunks_factory_impl.h"

using testing::_;
using testing::Invoke;
using testing::NiceMock;
using testing::Return;

namespace trunks {

class TrunksFactoryTest : public testing::Test {
 public:
  TrunksFactoryTest() : factory_(&mock_transceiver_) {}
  void SetUp() override {
    ON_CALL(mock_transceiver_, SendCommand(_, _))
        .WillByDefault(Invoke(this, &TrunksFactoryTest::SendCommand));
    ON_CALL(mock_transceiver_, SendCommandAndWait(_))
        .WillByDefault(Invoke(this, &TrunksFactoryTest::SendCommandAndWait));
  }

 protected:
  static std::string BuildSimpleResponse(TPM_RC rc) {
    constexpr int kResponseHeaderSize = 10;
    std::string response;
    Serialize_TPMI_ST_COMMAND_TAG(TPM_ST_NO_SESSIONS, &response);
    Serialize_UINT32(kResponseHeaderSize, &response);
    Serialize_TPM_RC(rc, &response);
    CHECK_EQ(response.size(), kResponseHeaderSize);
    return response;
  }

  void SendCommand(const std::string& command,
                   const CommandTransceiver::ResponseCallback& callback) {
    callback.Run(SendCommandAndWait(command));
  }

  std::string SendCommandAndWait(const std::string& command) {
    last_command_ = command;
    return next_response_;
  }

  std::string last_command_;
  std::string next_response_;
  NiceMock<MockCommandTransceiver> mock_transceiver_;
  TrunksFactoryImpl factory_;
};

TEST_F(TrunksFactoryTest, TpmSendCommand) {
  EXPECT_TRUE(factory_.Initialize());
  for (TPM_RC expected_code : {TPM_RC_SUCCESS, TPM_RC_FAILURE}) {
    next_response_ = BuildSimpleResponse(expected_code);
    auto callback = [](TPM_RC expected_code, TPM_RC response_code) {
      EXPECT_EQ(expected_code, response_code);
    };
    factory_.GetTpm()->Startup(TPM_SU_CLEAR, nullptr,
                               base::Bind(callback, expected_code));
    EXPECT_EQ(expected_code,
              factory_.GetTpm()->StartupSync(TPM_SU_CLEAR, nullptr));
  }
}

TEST_F(TrunksFactoryTest, TpmSendCommandRetry) {
  EXPECT_TRUE(factory_.Initialize());
  // Async versions of Tpm commands return responses "as is" without any
  // retry logic.
  next_response_ = BuildSimpleResponse(TPM_RC_RETRY);
  auto callback = [](TPM_RC response_code) {
    EXPECT_EQ(TPM_RC_RETRY, response_code);
  };
  factory_.GetTpm()->Startup(TPM_SU_CLEAR, nullptr, base::Bind(callback));
  // Sync versions of Tpm commands that call SendCommandAndWait should
  // retry when TPM_RC_RETRY and similar response codes are received.
  factory_.set_command_retry_delay(base::TimeDelta());
  factory_.set_max_command_retries(2);
  // Retries for (max_command_retries-1) attempts.
  EXPECT_CALL(mock_transceiver_, SendCommandAndWait(_))
      .WillOnce(Return(BuildSimpleResponse(TPM_RC_RETRY)))
      .WillOnce(Return(BuildSimpleResponse(TPM_RC_SUCCESS)));
  EXPECT_EQ(TPM_RC_SUCCESS,
            factory_.GetTpm()->StartupSync(TPM_SU_CLEAR, nullptr));
  // Retries for max_command_retries attempts.
  testing::Mock::VerifyAndClearExpectations(&mock_transceiver_);
  EXPECT_CALL(mock_transceiver_, SendCommandAndWait(_))
      .WillOnce(Return(BuildSimpleResponse(TPM_RC_RETRY)))
      .WillOnce(Return(BuildSimpleResponse(TPM_RC_RETRY)))
      .WillOnce(Return(BuildSimpleResponse(TPM_RC_SUCCESS)));
  EXPECT_EQ(TPM_RC_SUCCESS,
            factory_.GetTpm()->StartupSync(TPM_SU_CLEAR, nullptr));
  // Retries for >max_command_retries attempts.
  // Sync versions should give up after max number of retries.
  testing::Mock::VerifyAndClearExpectations(&mock_transceiver_);
  EXPECT_CALL(mock_transceiver_, SendCommandAndWait(_))
      .Times(3)
      .WillRepeatedly(Return(BuildSimpleResponse(TPM_RC_RETRY)));
  EXPECT_EQ(TPM_RC_RETRY,
            factory_.GetTpm()->StartupSync(TPM_SU_CLEAR, nullptr));
}

}  // namespace trunks
