/*
 *  Copyright 2017 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "rtc_base/fake_ssl_identity.h"

#include <memory>
#include <string>
#include <utility>

#include "absl/strings/string_view.h"
#include "rtc_base/checks.h"
#include "rtc_base/message_digest.h"

namespace webrtc {

FakeSSLCertificate::FakeSSLCertificate(absl::string_view pem_string)
    : pem_string_(pem_string),
      digest_algorithm_(rtc::DIGEST_SHA_1),
      expiration_time_(-1) {}

FakeSSLCertificate::FakeSSLCertificate(const FakeSSLCertificate&) = default;

FakeSSLCertificate::~FakeSSLCertificate() = default;

std::unique_ptr<rtc::SSLCertificate> FakeSSLCertificate::Clone() const {
  return std::make_unique<FakeSSLCertificate>(*this);
}

std::string FakeSSLCertificate::ToPEMString() const {
  return pem_string_;
}

void FakeSSLCertificate::ToDER(Buffer* der_buffer) const {
  std::string der_string;
  RTC_CHECK(rtc::SSLIdentity::PemToDer(rtc::kPemTypeCertificate, pem_string_,
                                       &der_string));
  der_buffer->SetData(der_string.c_str(), der_string.size());
}

int64_t FakeSSLCertificate::CertificateExpirationTime() const {
  return expiration_time_;
}

void FakeSSLCertificate::SetCertificateExpirationTime(int64_t expiration_time) {
  expiration_time_ = expiration_time;
}

void FakeSSLCertificate::set_digest_algorithm(absl::string_view algorithm) {
  digest_algorithm_ = std::string(algorithm);
}

bool FakeSSLCertificate::GetSignatureDigestAlgorithm(
    std::string* algorithm) const {
  *algorithm = digest_algorithm_;
  return true;
}

bool FakeSSLCertificate::ComputeDigest(absl::string_view algorithm,
                                       unsigned char* digest,
                                       size_t size,
                                       size_t* length) const {
  *length = rtc::ComputeDigest(algorithm, pem_string_.c_str(),
                               pem_string_.size(), digest, size);
  return (*length != 0);
}

FakeSSLIdentity::FakeSSLIdentity(absl::string_view pem_string)
    : FakeSSLIdentity(FakeSSLCertificate(pem_string)) {}

FakeSSLIdentity::FakeSSLIdentity(const std::vector<std::string>& pem_strings) {
  std::vector<std::unique_ptr<rtc::SSLCertificate>> certs;
  certs.reserve(pem_strings.size());
  for (const std::string& pem_string : pem_strings) {
    certs.push_back(std::make_unique<FakeSSLCertificate>(pem_string));
  }
  cert_chain_ = std::make_unique<rtc::SSLCertChain>(std::move(certs));
}

FakeSSLIdentity::FakeSSLIdentity(const FakeSSLCertificate& cert)
    : cert_chain_(std::make_unique<rtc::SSLCertChain>(cert.Clone())) {}

FakeSSLIdentity::FakeSSLIdentity(const FakeSSLIdentity& o)
    : cert_chain_(o.cert_chain_->Clone()) {}

FakeSSLIdentity::~FakeSSLIdentity() = default;

std::unique_ptr<rtc::SSLIdentity> FakeSSLIdentity::CloneInternal() const {
  return std::make_unique<FakeSSLIdentity>(*this);
}

const rtc::SSLCertificate& FakeSSLIdentity::certificate() const {
  return cert_chain_->Get(0);
}

const rtc::SSLCertChain& FakeSSLIdentity::cert_chain() const {
  return *cert_chain_.get();
}

std::string FakeSSLIdentity::PrivateKeyToPEMString() const {
  RTC_DCHECK_NOTREACHED();  // Not implemented.
  return "";
}

std::string FakeSSLIdentity::PublicKeyToPEMString() const {
  RTC_DCHECK_NOTREACHED();  // Not implemented.
  return "";
}

bool FakeSSLIdentity::operator==(const rtc::SSLIdentity& other) const {
  RTC_DCHECK_NOTREACHED();  // Not implemented.
  return false;
}

}  // namespace webrtc
