#include "quiche/oblivious_http/buffers/oblivious_http_request.h"

#include <stddef.h>

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

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "openssl/hkdf.h"
#include "openssl/hpke.h"
#include "quiche/common/platform/api/quiche_test.h"
#include "quiche/common/quiche_data_reader.h"
#include "quiche/oblivious_http/common/oblivious_http_header_key_config.h"

namespace quiche {

namespace {
const uint32_t kHeaderLength = ObliviousHttpHeaderKeyConfig::kHeaderLength;
std::string GetHpkePrivateKey() {
  absl::string_view hpke_key_hex =
      "b77431ecfa8f4cfc30d6e467aafa06944dffe28cb9dd1409e33a3045f5adc8a1";
  return absl::HexStringToBytes(hpke_key_hex);
}

std::string GetHpkePublicKey() {
  absl::string_view public_key =
      "6d21cfe09fbea5122f9ebc2eb2a69fcc4f06408cd54aac934f012e76fcdcef62";
  return absl::HexStringToBytes(public_key);
}

std::string GetAlternativeHpkePublicKey() {
  absl::string_view public_key =
      "6d21cfe09fbea5122f9ebc2eb2a69fcc4f06408cd54aac934f012e76fcdcef63";
  return absl::HexStringToBytes(public_key);
}

std::string GetSeed() {
  absl::string_view seed =
      "52c4a758a802cd8b936eceea314432798d5baf2d7e9235dc084ab1b9cfa2f736";
  return absl::HexStringToBytes(seed);
}

std::string GetSeededEncapsulatedKey() {
  absl::string_view encapsulated_key =
      "37fda3567bdbd628e88668c3c8d7e97d1d1253b6d4ea6d44c150f741f1bf4431";
  return absl::HexStringToBytes(encapsulated_key);
}

bssl::UniquePtr<EVP_HPKE_KEY> ConstructHpkeKey(
    absl::string_view hpke_key,
    const ObliviousHttpHeaderKeyConfig &ohttp_key_config) {
  bssl::UniquePtr<EVP_HPKE_KEY> bssl_hpke_key(EVP_HPKE_KEY_new());
  EXPECT_NE(bssl_hpke_key, nullptr);
  EXPECT_TRUE(EVP_HPKE_KEY_init(
      bssl_hpke_key.get(), ohttp_key_config.GetHpkeKem(),
      reinterpret_cast<const uint8_t *>(hpke_key.data()), hpke_key.size()));
  return bssl_hpke_key;
}

const ObliviousHttpHeaderKeyConfig GetOhttpKeyConfig(uint8_t key_id,
                                                     uint16_t kem_id,
                                                     uint16_t kdf_id,
                                                     uint16_t aead_id) {
  auto ohttp_key_config =
      ObliviousHttpHeaderKeyConfig::Create(key_id, kem_id, kdf_id, aead_id);
  EXPECT_TRUE(ohttp_key_config.ok());
  return std::move(ohttp_key_config.value());
}
}  // namespace

// Direct test example from OHttp spec.
// https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#appendix-A
TEST(ObliviousHttpRequest, TestDecapsulateWithSpecAppendixAExample) {
  auto ohttp_key_config =
      GetOhttpKeyConfig(/*key_id=*/1, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_128_GCM);

  // X25519 Secret key (priv key).
  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#appendix-A-2
  constexpr absl::string_view kX25519SecretKey =
      "3c168975674b2fa8e465970b79c8dcf09f1c741626480bd4c6162fc5b6a98e1a";

  // Encapsulated request.
  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#appendix-A-14
  constexpr absl::string_view kEncapsulatedRequest =
      "010020000100014b28f881333e7c164ffc499ad9796f877f4e1051ee6d31bad19dec96c2"
      "08b4726374e469135906992e1268c594d2a10c695d858c40a026e7965e7d86b83dd440b2"
      "c0185204b4d63525";

  // Initialize Request obj to Decapsulate (decrypt).
  auto instance = ObliviousHttpRequest::CreateServerObliviousRequest(
      absl::HexStringToBytes(kEncapsulatedRequest),
      *(ConstructHpkeKey(absl::HexStringToBytes(kX25519SecretKey),
                         ohttp_key_config)),
      ohttp_key_config);
  ASSERT_TRUE(instance.ok());
  auto decrypted = instance->GetPlaintextData();

  // Encapsulated/Ephemeral public key.
  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#appendix-A-10
  constexpr absl::string_view kExpectedEphemeralPublicKey =
      "4b28f881333e7c164ffc499ad9796f877f4e1051ee6d31bad19dec96c208b472";
  auto oblivious_request_context = std::move(instance.value()).ReleaseContext();
  EXPECT_EQ(oblivious_request_context.encapsulated_key_,
            absl::HexStringToBytes(kExpectedEphemeralPublicKey));

  // Binary HTTP message.
  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#appendix-A-6
  constexpr absl::string_view kExpectedBinaryHTTPMessage =
      "00034745540568747470730b6578616d706c652e636f6d012f";
  EXPECT_EQ(decrypted, absl::HexStringToBytes(kExpectedBinaryHTTPMessage));
}

TEST(ObliviousHttpRequest, TestEncapsulatedRequestStructure) {
  uint8_t test_key_id = 7;
  uint16_t test_kem_id = EVP_HPKE_DHKEM_X25519_HKDF_SHA256;
  uint16_t test_kdf_id = EVP_HPKE_HKDF_SHA256;
  uint16_t test_aead_id = EVP_HPKE_AES_256_GCM;
  std::string plaintext = "test";
  auto instance = ObliviousHttpRequest::CreateClientObliviousRequest(
      plaintext, GetHpkePublicKey(),
      GetOhttpKeyConfig(test_key_id, test_kem_id, test_kdf_id, test_aead_id));
  ASSERT_TRUE(instance.ok());
  auto payload_bytes = instance->EncapsulateAndSerialize();
  EXPECT_GE(payload_bytes.size(), kHeaderLength);
  // Parse header.
  QuicheDataReader reader(payload_bytes);
  uint8_t key_id;
  EXPECT_TRUE(reader.ReadUInt8(&key_id));
  EXPECT_EQ(key_id, test_key_id);
  uint16_t kem_id;
  EXPECT_TRUE(reader.ReadUInt16(&kem_id));
  EXPECT_EQ(kem_id, test_kem_id);
  uint16_t kdf_id;
  EXPECT_TRUE(reader.ReadUInt16(&kdf_id));
  EXPECT_EQ(kdf_id, test_kdf_id);
  uint16_t aead_id;
  EXPECT_TRUE(reader.ReadUInt16(&aead_id));
  EXPECT_EQ(aead_id, test_aead_id);
  auto client_request_context = std::move(instance.value()).ReleaseContext();
  auto client_encapsulated_key = client_request_context.encapsulated_key_;
  EXPECT_EQ(client_encapsulated_key.size(), X25519_PUBLIC_VALUE_LEN);
  auto enc_key_plus_ciphertext = payload_bytes.substr(kHeaderLength);
  auto packed_encapsulated_key =
      enc_key_plus_ciphertext.substr(0, X25519_PUBLIC_VALUE_LEN);
  EXPECT_EQ(packed_encapsulated_key, client_encapsulated_key);
  auto ciphertext = enc_key_plus_ciphertext.substr(X25519_PUBLIC_VALUE_LEN);
  EXPECT_GE(ciphertext.size(), plaintext.size());
}

TEST(ObliviousHttpRequest, TestDeterministicSeededOhttpRequest) {
  auto ohttp_key_config =
      GetOhttpKeyConfig(4, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
  auto encapsulated = ObliviousHttpRequest::CreateClientWithSeedForTesting(
      "test", GetHpkePublicKey(), ohttp_key_config, GetSeed());
  ASSERT_TRUE(encapsulated.ok());
  auto encapsulated_request = encapsulated->EncapsulateAndSerialize();
  auto ohttp_request_context = std::move(encapsulated.value()).ReleaseContext();
  EXPECT_EQ(ohttp_request_context.encapsulated_key_,
            GetSeededEncapsulatedKey());
  absl::string_view expected_encrypted_request =
      "9f37cfed07d0111ecd2c34f794671759bcbd922a";
  EXPECT_NE(ohttp_request_context.hpke_context_, nullptr);
  size_t encapsulated_key_len = EVP_HPKE_KEM_enc_len(
      EVP_HPKE_CTX_kem(ohttp_request_context.hpke_context_.get()));
  int encrypted_payload_offset = kHeaderLength + encapsulated_key_len;
  EXPECT_EQ(encapsulated_request.substr(encrypted_payload_offset),
            absl::HexStringToBytes(expected_encrypted_request));
}

TEST(ObliviousHttpRequest,
     TestSeededEncapsulatedKeySamePlaintextsSameCiphertexts) {
  auto ohttp_key_config =
      GetOhttpKeyConfig(8, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
  auto req_with_same_plaintext_1 =
      ObliviousHttpRequest::CreateClientWithSeedForTesting(
          "same plaintext", GetHpkePublicKey(), ohttp_key_config, GetSeed());
  ASSERT_TRUE(req_with_same_plaintext_1.ok());
  auto ciphertext_1 = req_with_same_plaintext_1->EncapsulateAndSerialize();
  auto req_with_same_plaintext_2 =
      ObliviousHttpRequest::CreateClientWithSeedForTesting(
          "same plaintext", GetHpkePublicKey(), ohttp_key_config, GetSeed());
  ASSERT_TRUE(req_with_same_plaintext_2.ok());
  auto ciphertext_2 = req_with_same_plaintext_2->EncapsulateAndSerialize();
  EXPECT_EQ(ciphertext_1, ciphertext_2);
}

TEST(ObliviousHttpRequest,
     TestSeededEncapsulatedKeyDifferentPlaintextsDifferentCiphertexts) {
  auto ohttp_key_config =
      GetOhttpKeyConfig(8, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
  auto req_with_different_plaintext_1 =
      ObliviousHttpRequest::CreateClientWithSeedForTesting(
          "different 1", GetHpkePublicKey(), ohttp_key_config, GetSeed());
  ASSERT_TRUE(req_with_different_plaintext_1.ok());
  auto ciphertext_1 = req_with_different_plaintext_1->EncapsulateAndSerialize();
  auto req_with_different_plaintext_2 =
      ObliviousHttpRequest::CreateClientWithSeedForTesting(
          "different 2", GetHpkePublicKey(), ohttp_key_config, GetSeed());
  ASSERT_TRUE(req_with_different_plaintext_2.ok());
  auto ciphertext_2 = req_with_different_plaintext_2->EncapsulateAndSerialize();
  EXPECT_NE(ciphertext_1, ciphertext_2);
}

TEST(ObliviousHttpRequest, TestInvalidInputsOnClientSide) {
  auto ohttp_key_config =
      GetOhttpKeyConfig(30, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
  // Empty plaintext.
  EXPECT_EQ(ObliviousHttpRequest::CreateClientObliviousRequest(
                /*plaintext_payload*/ "", GetHpkePublicKey(), ohttp_key_config)
                .status()
                .code(),
            absl::StatusCode::kInvalidArgument);
  // Empty HPKE public key.
  EXPECT_EQ(ObliviousHttpRequest::CreateClientObliviousRequest(
                "some plaintext",
                /*hpke_public_key*/ "", ohttp_key_config)
                .status()
                .code(),
            absl::StatusCode::kInvalidArgument);
}

TEST(ObliviousHttpRequest, TestInvalidInputsOnServerSide) {
  auto ohttp_key_config =
      GetOhttpKeyConfig(4, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
  // Empty encrypted payload.
  EXPECT_EQ(ObliviousHttpRequest::CreateServerObliviousRequest(
                /*encrypted_data*/ "",
                *(ConstructHpkeKey(GetHpkePrivateKey(), ohttp_key_config)),
                ohttp_key_config)
                .status()
                .code(),
            absl::StatusCode::kInvalidArgument);
  // Empty EVP_HPKE_KEY struct.
  EXPECT_EQ(ObliviousHttpRequest::CreateServerObliviousRequest(
                absl::StrCat(ohttp_key_config.SerializeOhttpPayloadHeader(),
                             GetSeededEncapsulatedKey(),
                             "9f37cfed07d0111ecd2c34f794671759bcbd922a"),
                /*gateway_key*/ {}, ohttp_key_config)
                .status()
                .code(),
            absl::StatusCode::kInvalidArgument);
}

TEST(ObliviousHttpRequest, EndToEndTestForRequest) {
  auto ohttp_key_config =
      GetOhttpKeyConfig(5, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
  auto encapsulate = ObliviousHttpRequest::CreateClientObliviousRequest(
      "test", GetHpkePublicKey(), ohttp_key_config);
  ASSERT_TRUE(encapsulate.ok());
  auto oblivious_request = encapsulate->EncapsulateAndSerialize();
  auto decapsulate = ObliviousHttpRequest::CreateServerObliviousRequest(
      oblivious_request,
      *(ConstructHpkeKey(GetHpkePrivateKey(), ohttp_key_config)),
      ohttp_key_config);
  ASSERT_TRUE(decapsulate.ok());
  auto decrypted = decapsulate->GetPlaintextData();
  EXPECT_EQ(decrypted, "test");
}

TEST(ObliviousHttpRequest, EndToEndTestForRequestWithWrongKey) {
  auto ohttp_key_config =
      GetOhttpKeyConfig(5, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
  auto encapsulate = ObliviousHttpRequest::CreateClientObliviousRequest(
      "test", GetAlternativeHpkePublicKey(), ohttp_key_config);
  ASSERT_TRUE(encapsulate.ok());
  auto oblivious_request = encapsulate->EncapsulateAndSerialize();
  auto decapsulate = ObliviousHttpRequest::CreateServerObliviousRequest(
      oblivious_request,
      *(ConstructHpkeKey(GetHpkePrivateKey(), ohttp_key_config)),
      ohttp_key_config);
  EXPECT_EQ(decapsulate.status().code(), absl::StatusCode::kInvalidArgument);
}
}  // namespace quiche
