// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "testing/pem.h"

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

#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "openssl/bio.h"
#include "openssl/ec.h"
#include "openssl/ec_key.h"
#include "openssl/evp.h"
#include "openssl/mem.h"
#include "openssl/nid.h"
#include "openssl/obj.h"
#include "openssl/pem.h"
#include "openssl/x509.h"
#include "proto/common.pb.h"
#include "tink/cleartext_keyset_handle.h"
#include "tink/keyset_handle.h"
#include "tink/public_key_sign.h"
#include "tink/signature/config_v0.h"
#include "tink/signature/signature_pem_keyset_reader.h"

namespace credentio {

using ::crypto::tink::PemKeyParams;
using ::crypto::tink::PublicKeySign;
using ::crypto::tink::SignaturePemKeysetReaderBuilder;

absl::StatusOr<std::unique_ptr<crypto::tink::PublicKeySign>> LoadTestKeyFromPem(
    absl::string_view pem, const PemKeyParams& key_params) {
  crypto::tink::SignaturePemKeysetReaderBuilder builder(
      SignaturePemKeysetReaderBuilder::PemReaderType::PUBLIC_KEY_SIGN);
  builder.Add({
      .serialized_key = std::string(pem),
      .parameters = key_params,
  });
  ABSL_ASSIGN_OR_RETURN(auto reader, builder.Build());
  ABSL_ASSIGN_OR_RETURN(auto handle, crypto::tink::CleartextKeysetHandle::Read(
                                         std::move(reader)));
  return handle->GetPrimitive<crypto::tink::PublicKeySign>(
      crypto::tink::ConfigSignatureV0());
}

absl::StatusOr<std::string> LoadOcspResponseFromPem(absl::string_view pem) {
  bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem.data(), pem.size()));
  if (bio == nullptr) {
    return absl::InternalError("Failed to create BIO.");
  }

  std::string response;
  bool found = false;
  while (true) {
    char* name = nullptr;
    char* header = nullptr;
    unsigned char* data = nullptr;
    int64_t len = 0;
    if (!PEM_read_bio(bio.get(), &name, &header, &data, &len)) {
      break;
    }
    bssl::UniquePtr<char> name_ptr(name);
    bssl::UniquePtr<char> header_ptr(header);
    bssl::UniquePtr<unsigned char> data_ptr(data);

    if (absl::string_view(name) == "OCSP RESPONSE") {
      if (found) {
        return absl::InvalidArgumentError(
            "Multiple OCSP RESPONSE blocks found; expected only one.");
      }
      response = std::string(reinterpret_cast<char*>(data), len);
      found = true;
    }
  }

  if (!found) {
    return absl::InvalidArgumentError("No OCSP RESPONSE block found.");
  }

  return response;
}

}  // namespace credentio
