// Copyright (c) 2018 The Chromium 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 "net/third_party/quiche/src/quic/core/http/http_encoder.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"

namespace quic {
namespace test {

class HttpEncoderTest : public QuicTest {
 public:
  HttpEncoderTest() {}
  HttpEncoder encoder_;
};

TEST_F(HttpEncoderTest, SerializeDataFrameHeader) {
  std::unique_ptr<char[]> buffer;
  uint64_t length =
      encoder_.SerializeDataFrameHeader(/* payload_length = */ 5, &buffer);
  char output[] = {// length
                   0x05,
                   // type (DATA)
                   0x00};
  EXPECT_EQ(QUIC_ARRAYSIZE(output), length);
  CompareCharArraysWithHexError("DATA", buffer.get(), length, output,
                                QUIC_ARRAYSIZE(output));
}

TEST_F(HttpEncoderTest, SerializeHeadersFrameHeader) {
  std::unique_ptr<char[]> buffer;
  uint64_t length =
      encoder_.SerializeHeadersFrameHeader(/* payload_length = */ 7, &buffer);
  char output[] = {// length
                   0x07,
                   // type (HEADERS)
                   0x01};
  EXPECT_EQ(QUIC_ARRAYSIZE(output), length);
  CompareCharArraysWithHexError("HEADERS", buffer.get(), length, output,
                                QUIC_ARRAYSIZE(output));
}

TEST_F(HttpEncoderTest, SerializePriorityFrame) {
  PriorityFrame priority;
  priority.prioritized_type = REQUEST_STREAM;
  priority.dependency_type = REQUEST_STREAM;
  priority.exclusive = true;
  priority.prioritized_element_id = 0x03;
  priority.element_dependency_id = 0x04;
  priority.weight = 0xFF;
  char output[] = {// length
                   0x4,
                   // type (PRIORITY)
                   0x2,
                   // request stream, request stream, exclusive
                   0x01,
                   // prioritized_element_id
                   0x03,
                   // element_dependency_id
                   0x04,
                   // weight
                   0xFF};

  std::unique_ptr<char[]> buffer;
  uint64_t length = encoder_.SerializePriorityFrame(priority, &buffer);
  EXPECT_EQ(QUIC_ARRAYSIZE(output), length);
  CompareCharArraysWithHexError("PRIORITY", buffer.get(), length, output,
                                QUIC_ARRAYSIZE(output));
}

TEST_F(HttpEncoderTest, SerializeCancelPushFrame) {
  CancelPushFrame cancel_push;
  cancel_push.push_id = 0x01;
  char output[] = {// length
                   0x1,
                   // type (CANCEL_PUSH)
                   0x03,
                   // Push Id
                   0x01};
  std::unique_ptr<char[]> buffer;
  uint64_t length = encoder_.SerializeCancelPushFrame(cancel_push, &buffer);
  EXPECT_EQ(QUIC_ARRAYSIZE(output), length);
  CompareCharArraysWithHexError("CANCEL_PUSH", buffer.get(), length, output,
                                QUIC_ARRAYSIZE(output));
}

TEST_F(HttpEncoderTest, SerializeSettingsFrame) {
  SettingsFrame settings;
  settings.values[3] = 2;
  settings.values[6] = 5;
  char output[] = {
      // length
      0x06,
      // type (SETTINGS)
      0x04,
      // identifier (SETTINGS_NUM_PLACEHOLDERS)
      0x00,
      0x03,
      // content
      0x02,
      // identifier (SETTINGS_MAX_HEADER_LIST_SIZE)
      0x00,
      0x06,
      // content
      0x05,
  };
  std::unique_ptr<char[]> buffer;
  uint64_t length = encoder_.SerializeSettingsFrame(settings, &buffer);
  EXPECT_EQ(QUIC_ARRAYSIZE(output), length);
  CompareCharArraysWithHexError("SETTINGS", buffer.get(), length, output,
                                QUIC_ARRAYSIZE(output));
}

TEST_F(HttpEncoderTest, SerializePushPromiseFrameWithOnlyPushId) {
  PushPromiseFrame push_promise;
  push_promise.push_id = 0x01;
  push_promise.headers = "Headers";
  char output[] = {// length
                   0x8,
                   // type (PUSH_PROMISE)
                   0x05,
                   // Push Id
                   0x01};
  std::unique_ptr<char[]> buffer;
  uint64_t length =
      encoder_.SerializePushPromiseFrameWithOnlyPushId(push_promise, &buffer);
  EXPECT_EQ(QUIC_ARRAYSIZE(output), length);
  CompareCharArraysWithHexError("PUSH_PROMISE", buffer.get(), length, output,
                                QUIC_ARRAYSIZE(output));
}

TEST_F(HttpEncoderTest, SerializeGoAwayFrame) {
  GoAwayFrame goaway;
  goaway.stream_id = 0x1;
  char output[] = {// length
                   0x1,
                   // type (GOAWAY)
                   0x07,
                   // StreamId
                   0x01};
  std::unique_ptr<char[]> buffer;
  uint64_t length = encoder_.SerializeGoAwayFrame(goaway, &buffer);
  EXPECT_EQ(QUIC_ARRAYSIZE(output), length);
  CompareCharArraysWithHexError("GOAWAY", buffer.get(), length, output,
                                QUIC_ARRAYSIZE(output));
}

TEST_F(HttpEncoderTest, SerializeMaxPushIdFrame) {
  MaxPushIdFrame max_push_id;
  max_push_id.push_id = 0x1;
  char output[] = {// length
                   0x1,
                   // type (MAX_PUSH_ID)
                   0x0D,
                   // Push Id
                   0x01};
  std::unique_ptr<char[]> buffer;
  uint64_t length = encoder_.SerializeMaxPushIdFrame(max_push_id, &buffer);
  EXPECT_EQ(QUIC_ARRAYSIZE(output), length);
  CompareCharArraysWithHexError("MAX_PUSH_ID", buffer.get(), length, output,
                                QUIC_ARRAYSIZE(output));
}

TEST_F(HttpEncoderTest, SerializeDuplicatePushFrame) {
  DuplicatePushFrame duplicate_push;
  duplicate_push.push_id = 0x1;
  char output[] = {// length
                   0x1,
                   // type (DUPLICATE_PUSH)
                   0x0E,
                   // Push Id
                   0x01};
  std::unique_ptr<char[]> buffer;
  uint64_t length =
      encoder_.SerializeDuplicatePushFrame(duplicate_push, &buffer);
  EXPECT_EQ(QUIC_ARRAYSIZE(output), length);
  CompareCharArraysWithHexError("DUPLICATE_PUSH", buffer.get(), length, output,
                                QUIC_ARRAYSIZE(output));
}

}  // namespace test
}  // namespace quic
