#include "quiche/http2/adapter/noop_header_validator.h"

#include <utility>
#include <vector>

#include "absl/strings/str_cat.h"
#include "absl/types/optional.h"
#include "quiche/common/platform/api/quiche_test.h"

namespace http2 {
namespace adapter {
namespace test {

using ::testing::Optional;

using Header = std::pair<absl::string_view, absl::string_view>;
constexpr Header kSampleRequestPseudoheaders[] = {{":authority", "www.foo.com"},
                                                  {":method", "GET"},
                                                  {":path", "/foo"},
                                                  {":scheme", "https"}};

TEST(NoopHeaderValidatorTest, HeaderNameEmpty) {
  NoopHeaderValidator v;
  NoopHeaderValidator::HeaderStatus status =
      v.ValidateSingleHeader("", "value");
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK, status);
}

TEST(NoopHeaderValidatorTest, HeaderValueEmpty) {
  NoopHeaderValidator v;
  NoopHeaderValidator::HeaderStatus status = v.ValidateSingleHeader("name", "");
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK, status);
}

TEST(NoopHeaderValidatorTest, ExceedsMaxSize) {
  NoopHeaderValidator v;
  v.SetMaxFieldSize(64u);
  NoopHeaderValidator::HeaderStatus status =
      v.ValidateSingleHeader("name", "value");
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK, status);
  status = v.ValidateSingleHeader(
      "name2",
      "Antidisestablishmentariansism is supercalifragilisticexpialodocious.");
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK, status);
}

TEST(NoopHeaderValidatorTest, AnyNameCharIsValid) {
  NoopHeaderValidator v;
  char pseudo_name[] = ":met hod";
  char name[] = "na me";
  for (int i = std::numeric_limits<char>::min();
       i < std::numeric_limits<char>::max(); ++i) {
    char c = static_cast<char>(i);
    // Test a pseudo-header name with this char.
    pseudo_name[3] = c;
    auto sv = absl::string_view(pseudo_name, 8);
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(sv, "value"));
    // Test a regular header name with this char.
    name[2] = c;
    sv = absl::string_view(name, 5);
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(sv, "value"));
  }
}

TEST(NoopHeaderValidatorTest, AnyValueCharIsValid) {
  NoopHeaderValidator v;
  char value[] = "val ue";
  for (int i = std::numeric_limits<char>::min();
       i < std::numeric_limits<char>::max(); ++i) {
    char c = static_cast<char>(i);
    value[3] = c;
    auto sv = absl::string_view(value, 6);
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader("name", sv));
  }
}

TEST(NoopHeaderValidatorTest, AnyStatusIsValid) {
  NoopHeaderValidator v;

  for (HeaderType type : {HeaderType::RESPONSE, HeaderType::RESPONSE_100}) {
    v.StartHeaderBlock();
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(":status", "bar"));
    EXPECT_TRUE(v.FinishHeaderBlock(type));

    v.StartHeaderBlock();
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(":status", "10"));
    EXPECT_TRUE(v.FinishHeaderBlock(type));

    v.StartHeaderBlock();
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(":status", "9000"));
    EXPECT_TRUE(v.FinishHeaderBlock(type));

    v.StartHeaderBlock();
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(":status", "400"));
    EXPECT_TRUE(v.FinishHeaderBlock(type));
  }
}

TEST(NoopHeaderValidatorTest, AnyAuthorityCharIsValid) {
  char value[] = "ho st.example.com";
  for (int i = std::numeric_limits<char>::min();
       i < std::numeric_limits<char>::max(); ++i) {
    char c = static_cast<char>(i);
    value[2] = c;
    auto sv = absl::string_view(value, 17);
    for (absl::string_view key : {":authority", "host"}) {
      NoopHeaderValidator v;
      v.StartHeaderBlock();
      EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(key, sv));
    }
  }
}

TEST(NoopHeaderValidatorTest, RequestHostAndAuthority) {
  NoopHeaderValidator v;
  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(to_add.first, to_add.second));
  }
  // If both "host" and ":authority" have the same value, validation succeeds.
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("host", "www.foo.com"));
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));

  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(to_add.first, to_add.second));
  }
  // If "host" and ":authority" have different values, validation still
  // succeeds.
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("host", "www.bar.com"));
}

TEST(NoopHeaderValidatorTest, RequestPseudoHeaders) {
  NoopHeaderValidator v;
  for (Header to_skip : kSampleRequestPseudoheaders) {
    v.StartHeaderBlock();
    for (Header to_add : kSampleRequestPseudoheaders) {
      if (to_add != to_skip) {
        EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
                  v.ValidateSingleHeader(to_add.first, to_add.second));
      }
    }
    // Even if a pseudo-header is missing, final validation will succeed.
    EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
  }

  // When all pseudo-headers are present, final validation will succeed.
  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(to_add.first, to_add.second));
  }
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));

  // When an extra pseudo-header is present, final validation will still
  // succeed.
  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(to_add.first, to_add.second));
  }
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":extra", "blah"));
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));

  // When a required pseudo-header is repeated, final validation will succeed.
  for (Header to_repeat : kSampleRequestPseudoheaders) {
    v.StartHeaderBlock();
    for (Header to_add : kSampleRequestPseudoheaders) {
      EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, to_add.second));
      if (to_add == to_repeat) {
        EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
                  v.ValidateSingleHeader(to_add.first, to_add.second));
      }
    }
    EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
  }
}

TEST(NoopHeaderValidatorTest, WebsocketPseudoHeaders) {
  NoopHeaderValidator v;
  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(to_add.first, to_add.second));
  }
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":protocol", "websocket"));
  // Validation always succeeds.
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));

  // This is a no-op for NoopHeaderValidator.
  v.SetAllowExtendedConnect();

  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(to_add.first, to_add.second));
  }
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":protocol", "websocket"));
  // The validator does not check for a CONNECT request.
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));

  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    if (to_add.first == ":method") {
      EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, "CONNECT"));
    } else {
      EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, to_add.second));
    }
  }
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":protocol", "websocket"));
  // After allowing the method, `:protocol` is acepted for CONNECT requests.
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
}

TEST(NoopHeaderValidatorTest, AsteriskPathPseudoHeader) {
  NoopHeaderValidator v;

  // The validator does not perform any path validation.
  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    if (to_add.first == ":path") {
      EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, "*"));
    } else {
      EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, to_add.second));
    }
  }
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));

  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    if (to_add.first == ":path") {
      EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, "*"));
    } else if (to_add.first == ":method") {
      EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, "OPTIONS"));
    } else {
      EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, to_add.second));
    }
  }
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
}

TEST(NoopHeaderValidatorTest, InvalidPathPseudoHeader) {
  NoopHeaderValidator v;

  // An empty path is allowed.
  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    if (to_add.first == ":path") {
      EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, ""));
    } else {
      EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, to_add.second));
    }
  }
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));

  // A path that does not start with a slash is allowed.
  v.StartHeaderBlock();
  for (Header to_add : kSampleRequestPseudoheaders) {
    if (to_add.first == ":path") {
      EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, "shawarma"));
    } else {
      EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(to_add.first, to_add.second));
    }
  }
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
}

TEST(NoopHeaderValidatorTest, ResponsePseudoHeaders) {
  NoopHeaderValidator v;

  for (HeaderType type : {HeaderType::RESPONSE, HeaderType::RESPONSE_100}) {
    // When `:status` is missing, validation succeeds.
    v.StartHeaderBlock();
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader("foo", "bar"));
    EXPECT_TRUE(v.FinishHeaderBlock(type));

    // When all pseudo-headers are present, final validation succeeds.
    v.StartHeaderBlock();
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(":status", "199"));
    EXPECT_TRUE(v.FinishHeaderBlock(type));
    EXPECT_EQ("199", v.status_header());

    // When `:status` is repeated, validation succeeds.
    v.StartHeaderBlock();
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(":status", "199"));
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(":status", "299"));
    EXPECT_TRUE(v.FinishHeaderBlock(type));

    // When an extra pseudo-header is present, final validation succeeds.
    v.StartHeaderBlock();
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(":status", "199"));
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(":extra", "blorp"));
    EXPECT_TRUE(v.FinishHeaderBlock(type));
  }
}

TEST(NoopHeaderValidatorTest, ResponseWithHost) {
  NoopHeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "200"));
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("host", "myserver.com"));
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
}

TEST(NoopHeaderValidatorTest, Response204) {
  NoopHeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "204"));
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("x-content", "is not present"));
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
}

TEST(NoopHeaderValidatorTest, ResponseWithMultipleIdenticalContentLength) {
  NoopHeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "200"));
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "13"));
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "13"));
}

TEST(NoopHeaderValidatorTest, ResponseWithMultipleDifferingContentLength) {
  NoopHeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "200"));
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "13"));
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "17"));
}

TEST(NoopHeaderValidatorTest, Response204WithContentLengthZero) {
  NoopHeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "204"));
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("x-content", "is not present"));
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "0"));
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
}

TEST(NoopHeaderValidatorTest, Response204WithContentLength) {
  NoopHeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "204"));
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("x-content", "is not present"));
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "1"));
}

TEST(NoopHeaderValidatorTest, Response100) {
  NoopHeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "100"));
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("x-content", "is not present"));
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
}

TEST(NoopHeaderValidatorTest, Response100WithContentLengthZero) {
  NoopHeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "100"));
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("x-content", "is not present"));
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "0"));
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
}

TEST(NoopHeaderValidatorTest, Response100WithContentLength) {
  NoopHeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "100"));
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("x-content", "is not present"));
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "1"));
}

TEST(NoopHeaderValidatorTest, ResponseTrailerPseudoHeaders) {
  NoopHeaderValidator v;

  // When no pseudo-headers are present, validation will succeed.
  v.StartHeaderBlock();
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("foo", "bar"));
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE_TRAILER));

  // When a pseudo-header is present, validation will succeed.
  v.StartHeaderBlock();
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader(":status", "200"));
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("foo", "bar"));
  EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE_TRAILER));
}

TEST(NoopHeaderValidatorTest, ValidContentLength) {
  NoopHeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(v.content_length(), absl::nullopt);
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "41"));
  EXPECT_EQ(v.content_length(), absl::nullopt);

  v.StartHeaderBlock();
  EXPECT_EQ(v.content_length(), absl::nullopt);
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "42"));
  EXPECT_EQ(v.content_length(), absl::nullopt);
}

TEST(NoopHeaderValidatorTest, InvalidContentLength) {
  NoopHeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(v.content_length(), absl::nullopt);
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", ""));
  EXPECT_EQ(v.content_length(), absl::nullopt);
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "nan"));
  EXPECT_EQ(v.content_length(), absl::nullopt);
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "-42"));
  EXPECT_EQ(v.content_length(), absl::nullopt);
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("content-length", "42"));
  EXPECT_EQ(v.content_length(), absl::nullopt);
}

TEST(NoopHeaderValidatorTest, TeHeader) {
  NoopHeaderValidator v;

  v.StartHeaderBlock();
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("te", "trailers"));

  v.StartHeaderBlock();
  EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
            v.ValidateSingleHeader("te", "trailers, deflate"));
}

TEST(NoopHeaderValidatorTest, ConnectionSpecificHeaders) {
  const std::vector<Header> connection_headers = {
      {"connection", "keep-alive"}, {"proxy-connection", "keep-alive"},
      {"keep-alive", "timeout=42"}, {"transfer-encoding", "chunked"},
      {"upgrade", "h2c"},
  };
  for (const auto& [connection_key, connection_value] : connection_headers) {
    NoopHeaderValidator v;
    v.StartHeaderBlock();
    for (const auto& [sample_key, sample_value] : kSampleRequestPseudoheaders) {
      EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
                v.ValidateSingleHeader(sample_key, sample_value));
    }
    EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
              v.ValidateSingleHeader(connection_key, connection_value));
  }
}

}  // namespace test
}  // namespace adapter
}  // namespace http2
