// Copyright 2014 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 "trunks/trunks_factory_impl.h"

#include <memory>

#include <base/check.h>
#include <base/logging.h>

#include "trunks/blob_parser.h"
#include "trunks/error_codes.h"
#include "trunks/hmac_session_impl.h"
#include "trunks/password_authorization_delegate.h"
#include "trunks/policy_session_impl.h"
#include "trunks/session_manager_impl.h"
#include "trunks/tpm_cache.h"
#include "trunks/tpm_cache_impl.h"
#include "trunks/tpm_generated.h"
#include "trunks/tpm_state_impl.h"
#include "trunks/tpm_utility_impl.h"
#include "trunks/trunks_dbus_proxy.h"

namespace {

constexpr int kDefaultRetryDelayInMS = 250;
constexpr int kDefaultRetryTimeoutInMS = 10 * 1000;
constexpr int kDefaultRetries =
    kDefaultRetryTimeoutInMS / kDefaultRetryDelayInMS;
constexpr base::TimeDelta kDefaultRetryDelay =
    base::TimeDelta::FromMilliseconds(kDefaultRetryDelayInMS);

}  // namespace

namespace trunks {

// A post-processing transceiver that attaches on top of the transceiver passed
// to TrunksFactoryImpl. Peforms the following functions:
// - Checks the response in SendCommandAndWait and retries the command
//   in case the response code requests a retry. See RetryNeededFor() for
//   details.
class TrunksFactoryImpl::PostProcessingTransceiver : public CommandTransceiver {
 public:
  explicit PostProcessingTransceiver(CommandTransceiver* transceiver)
      : command_retry_delay_(kDefaultRetryDelay),
        max_command_retries_(kDefaultRetries),
        transceiver_(transceiver) {
    CHECK(transceiver_);
  }
  PostProcessingTransceiver(const PostProcessingTransceiver&) = delete;
  PostProcessingTransceiver& operator=(const PostProcessingTransceiver&) =
      delete;

  void set_max_command_retries(int max_command_retries) {
    max_command_retries_ = max_command_retries;
  }

  void set_command_retry_delay(base::TimeDelta command_retry_delay) {
    command_retry_delay_ = command_retry_delay;
  }

  bool Init() override { return transceiver_->Init(); }

  void SendCommand(const std::string& command,
                   const ResponseCallback& callback) override {
    transceiver_->SendCommand(command, callback);
  }

  std::string SendCommandAndWait(const std::string& command) override {
    int attempt_num = 0;
    std::string response;
    do {
      if (attempt_num > 0) {
        base::PlatformThread::Sleep(command_retry_delay_);
      }
      response = transceiver_->SendCommandAndWait(command);
    } while (RetryNeededFor(response, ++attempt_num));
    VLOG_IF(2, attempt_num > 1) << "Command sent " << attempt_num << " times.";
    return response;
  }

 private:
  bool RetryNeededFor(const std::string& response, int attempt_num) {
    if (attempt_num > max_command_retries_) {
      LOG(WARNING) << "Gave up retrying command after " << attempt_num
                   << " attempts.";
      return false;
    }
    TPM_RC rc;
    if (!GetResponseCode(response, &rc)) {
      return false;
    }
    switch (rc) {
      case TPM_RC_RETRY:
      case TPM_RC_NV_RATE:
        if (attempt_num == 1) {
          LOG(WARNING) << "Retrying command after " << GetErrorString(rc);
        } else {
          VLOG(2) << "Retrying command after " << GetErrorString(rc);
        }
        return true;
      default:
        return false;
    }
  }

  bool GetResponseCode(const std::string& response, TPM_RC* rc) {
    DCHECK(rc);
    std::string buffer(response);
    trunks::TPM_ST tag;
    if (Parse_TPM_ST(&buffer, &tag, nullptr) != TPM_RC_SUCCESS) {
      return false;
    }
    trunks::UINT32 response_size;
    if (Parse_UINT32(&buffer, &response_size, nullptr) != TPM_RC_SUCCESS) {
      return false;
    }
    if (response_size != response.size()) {
      return false;
    }
    return Parse_TPM_RC(&buffer, rc, nullptr) == TPM_RC_SUCCESS;
  }

  base::TimeDelta command_retry_delay_;
  int max_command_retries_;
  CommandTransceiver* transceiver_;
};

TrunksFactoryImpl::TrunksFactoryImpl() {
  default_transceiver_.reset(new TrunksDBusProxy());
  transceiver_.reset(new PostProcessingTransceiver(default_transceiver_.get()));
}

TrunksFactoryImpl::TrunksFactoryImpl(CommandTransceiver* transceiver) {
  transceiver_.reset(new PostProcessingTransceiver(transceiver));
}

TrunksFactoryImpl::~TrunksFactoryImpl() {}

bool TrunksFactoryImpl::Initialize() {
  if (initialized_) {
    return true;
  }
  tpm_.reset(new Tpm(transceiver_.get()));
  tpm_cache_ = std::make_unique<TpmCacheImpl>(*this);
  if (!IsDefaultTransceiverUsed()) {
    initialized_ = true;
  } else {
    initialized_ = transceiver_->Init();
    if (!initialized_) {
      LOG(WARNING) << "Failed to initialize the trunks IPC proxy; "
                   << "trunksd is not ready.";
    }
  }
  return initialized_;
}

Tpm* TrunksFactoryImpl::GetTpm() const {
  return tpm_.get();
}

TpmCache* TrunksFactoryImpl::GetTpmCache() const {
  return tpm_cache_.get();
}

std::unique_ptr<TpmState> TrunksFactoryImpl::GetTpmState() const {
  return std::make_unique<TpmStateImpl>(*this);
}

std::unique_ptr<TpmUtility> TrunksFactoryImpl::GetTpmUtility() const {
  return std::make_unique<TpmUtilityImpl>(*this);
}

std::unique_ptr<AuthorizationDelegate>
TrunksFactoryImpl::GetPasswordAuthorization(const std::string& password) const {
  return std::make_unique<PasswordAuthorizationDelegate>(password);
}

std::unique_ptr<SessionManager> TrunksFactoryImpl::GetSessionManager() const {
  return std::make_unique<SessionManagerImpl>(*this);
}

std::unique_ptr<HmacSession> TrunksFactoryImpl::GetHmacSession() const {
  return std::make_unique<HmacSessionImpl>(*this);
}

std::unique_ptr<PolicySession> TrunksFactoryImpl::GetPolicySession() const {
  return std::make_unique<PolicySessionImpl>(*this, TPM_SE_POLICY);
}

std::unique_ptr<PolicySession> TrunksFactoryImpl::GetTrialSession() const {
  return std::make_unique<PolicySessionImpl>(*this, TPM_SE_TRIAL);
}

std::unique_ptr<BlobParser> TrunksFactoryImpl::GetBlobParser() const {
  return std::make_unique<BlobParser>();
}

void TrunksFactoryImpl::set_max_command_retries(int max_command_retries) {
  transceiver_->set_max_command_retries(max_command_retries);
}

void TrunksFactoryImpl::set_command_retry_delay(
    base::TimeDelta command_retry_delay) {
  transceiver_->set_command_retry_delay(command_retry_delay);
}

}  // namespace trunks
