// 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 "net/third_party/http2/tools/http2_frame_builder.h"

#ifdef STARBOARD
#include "starboard/client_porting/poem/inet_poem.h"
#else
#ifdef WIN32
#include <winsock2.h>  // for htonl() functions
#else
#include <arpa/inet.h>
#include <netinet/in.h>  // for htonl, htons
#endif
#endif  // STARBOARD

#include "net/third_party/http2/platform/api/http2_string_utils.h"
#include "starboard/types.h"
#include "testing/gtest/include/gtest/gtest.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(Http2StringPiece s) {
  Http2StrAppend(&buffer_, s);
}

void Http2FrameBuilder::AppendBytes(const void* data, uint32_t num_bytes) {
  Append(Http2StringPiece(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 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);
}

// Methods for changing existing buffer contents.

void Http2FrameBuilder::WriteAt(Http2StringPiece 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(Http2StringPiece(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
