// Copyright 2016 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 "http2/tools/http2_frame_builder.h"

#ifdef WIN32
#include <winsock2.h>  // for htonl() functions
#else
#include <arpa/inet.h>
#include <netinet/in.h>  // for htonl, htons
#endif

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

namespace http2 {
namespace test {

Http2FrameBuilder::Http2FrameBuilder(Http2FrameType type,
                                     uint8_t flags,
                                     uint32_t stream_id) {
  AppendUInt24(0);  // Frame payload length, unknown so far.
  Append(type);
  AppendUInt8(flags);
  AppendUInt31(stream_id);
}

Http2FrameBuilder::Http2FrameBuilder(const Http2FrameHeader& v) {
  Append(v);
}

void Http2FrameBuilder::Append(absl::string_view s) {
  absl::StrAppend(&buffer_, s);
}

void Http2FrameBuilder::AppendBytes(const void* data, uint32_t num_bytes) {
  Append(absl::string_view(static_cast<const char*>(data), num_bytes));
}

void Http2FrameBuilder::AppendZeroes(size_t num_zero_bytes) {
  char zero = 0;
  buffer_.append(num_zero_bytes, zero);
}

void Http2FrameBuilder::AppendUInt8(uint8_t value) {
  AppendBytes(&value, 1);
}

void Http2FrameBuilder::AppendUInt16(uint16_t value) {
  value = htons(value);
  AppendBytes(&value, 2);
}

void Http2FrameBuilder::AppendUInt24(uint32_t value) {
  // Doesn't make sense to try to append a larger value, as that doesn't
  // simulate something an encoder could do (i.e. the other 8 bits simply aren't
  // there to be occupied).
  EXPECT_EQ(value, value & 0xffffff);
  value = htonl(value);
  AppendBytes(reinterpret_cast<char*>(&value) + 1, 3);
}

void Http2FrameBuilder::AppendUInt31(uint32_t value) {
  // If you want to test the high-bit being set, call AppendUInt32 instead.
  uint32_t tmp = value & StreamIdMask();
  EXPECT_EQ(value, value & StreamIdMask())
      << "High-bit of uint32_t should be clear.";
  value = htonl(tmp);
  AppendBytes(&value, 4);
}

void Http2FrameBuilder::AppendUInt32(uint32_t value) {
  value = htonl(value);
  AppendBytes(&value, sizeof(value));
}

void Http2FrameBuilder::Append(Http2ErrorCode error_code) {
  AppendUInt32(static_cast<uint32_t>(error_code));
}

void Http2FrameBuilder::Append(Http2FrameType type) {
  AppendUInt8(static_cast<uint8_t>(type));
}

void Http2FrameBuilder::Append(Http2SettingsParameter parameter) {
  AppendUInt16(static_cast<uint16_t>(parameter));
}

void Http2FrameBuilder::Append(const Http2FrameHeader& v) {
  AppendUInt24(v.payload_length);
  Append(v.type);
  AppendUInt8(v.flags);
  AppendUInt31(v.stream_id);
}

void Http2FrameBuilder::Append(const Http2PriorityFields& v) {
  // The EXCLUSIVE flag is the high-bit of the 32-bit stream dependency field.
  uint32_t tmp = v.stream_dependency & StreamIdMask();
  EXPECT_EQ(tmp, v.stream_dependency);
  if (v.is_exclusive) {
    tmp |= 0x80000000;
  }
  AppendUInt32(tmp);

  // The PRIORITY frame's weight field is logically in the range [1, 256],
  // but is encoded as a byte in the range [0, 255].
  ASSERT_LE(1u, v.weight);
  ASSERT_LE(v.weight, 256u);
  AppendUInt8(v.weight - 1);
}

void Http2FrameBuilder::Append(const Http2RstStreamFields& v) {
  Append(v.error_code);
}

void Http2FrameBuilder::Append(const Http2SettingFields& v) {
  Append(v.parameter);
  AppendUInt32(v.value);
}

void Http2FrameBuilder::Append(const Http2PushPromiseFields& v) {
  AppendUInt31(v.promised_stream_id);
}

void Http2FrameBuilder::Append(const Http2PingFields& v) {
  AppendBytes(v.opaque_bytes, sizeof Http2PingFields::opaque_bytes);
}

void Http2FrameBuilder::Append(const Http2GoAwayFields& v) {
  AppendUInt31(v.last_stream_id);
  Append(v.error_code);
}

void Http2FrameBuilder::Append(const Http2WindowUpdateFields& v) {
  EXPECT_NE(0u, v.window_size_increment) << "Increment must be non-zero.";
  AppendUInt31(v.window_size_increment);
}

void Http2FrameBuilder::Append(const Http2AltSvcFields& v) {
  AppendUInt16(v.origin_length);
}

void Http2FrameBuilder::Append(const Http2PriorityUpdateFields& v) {
  AppendUInt31(v.prioritized_stream_id);
}

// Methods for changing existing buffer contents.

void Http2FrameBuilder::WriteAt(absl::string_view s, size_t offset) {
  ASSERT_LE(offset, buffer_.size());
  size_t len = offset + s.size();
  if (len > buffer_.size()) {
    buffer_.resize(len);
  }
  for (size_t ndx = 0; ndx < s.size(); ++ndx) {
    buffer_[offset + ndx] = s[ndx];
  }
}

void Http2FrameBuilder::WriteBytesAt(const void* data,
                                     uint32_t num_bytes,
                                     size_t offset) {
  WriteAt(absl::string_view(static_cast<const char*>(data), num_bytes), offset);
}

void Http2FrameBuilder::WriteUInt24At(uint32_t value, size_t offset) {
  ASSERT_LT(value, static_cast<uint32_t>(1 << 24));
  value = htonl(value);
  WriteBytesAt(reinterpret_cast<char*>(&value) + 1, sizeof(value) - 1, offset);
}

void Http2FrameBuilder::SetPayloadLength(uint32_t payload_length) {
  WriteUInt24At(payload_length, 0);
}

size_t Http2FrameBuilder::SetPayloadLength() {
  EXPECT_GE(size(), Http2FrameHeader::EncodedSize());
  uint32_t payload_length = size() - Http2FrameHeader::EncodedSize();
  SetPayloadLength(payload_length);
  return payload_length;
}

}  // namespace test
}  // namespace http2
