// 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/core/quic_data_writer.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"

namespace quic {

namespace {

// Set the first byte of a PRIORITY frame according to its fields.
uint8_t SetPriorityFields(uint8_t num,
                          PriorityElementType type,
                          bool prioritized) {
  switch (type) {
    case REQUEST_STREAM:
      return num;
    case PUSH_STREAM:
      if (prioritized) {
        return num | (1 << 6);
      }
      return num | (1 << 4);
    case PLACEHOLDER:
      if (prioritized) {
        return num | (1 << 7);
      }
      return num | (1 << 5);
    case ROOT_OF_TREE:
      if (prioritized) {
        num = num | (1 << 6);
        return num | (1 << 7);
      }
      num = num | (1 << 4);
      return num | (1 << 5);
    default:
      QUIC_NOTREACHED();
      return num;
  }
}

bool WriteFrameHeader(QuicByteCount length,
                      HttpFrameType type,
                      QuicDataWriter* writer) {
  return writer->WriteVarInt62(static_cast<uint64_t>(type)) &&
         writer->WriteVarInt62(length);
}

QuicByteCount GetTotalLength(QuicByteCount payload_length, HttpFrameType type) {
  return QuicDataWriter::GetVarInt62Len(payload_length) +
         QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(type)) +
         payload_length;
}

// Write prioritized element id and element dependency id if needed.
bool MaybeWriteIds(const PriorityFrame& priority, QuicDataWriter* writer) {
  if (priority.prioritized_type != ROOT_OF_TREE) {
    if (!writer->WriteVarInt62(priority.prioritized_element_id)) {
      return false;
    }
  } else {
    DCHECK_EQ(0u, priority.prioritized_element_id)
        << "Prioritized element id should be 0 when prioritized type is "
           "ROOT_OF_TREE";
  }
  if (priority.dependency_type != ROOT_OF_TREE) {
    if (!writer->WriteVarInt62(priority.element_dependency_id)) {
      return false;
    }
  } else {
    DCHECK_EQ(0u, priority.element_dependency_id)
        << "Element dependency id should be 0 when dependency type is "
           "ROOT_OF_TREE";
  }
  return true;
}

}  // namespace

// static
QuicByteCount HttpEncoder::SerializeDataFrameHeader(
    QuicByteCount payload_length,
    std::unique_ptr<char[]>* output) {
  DCHECK_NE(0u, payload_length);
  QuicByteCount header_length = QuicDataWriter::GetVarInt62Len(payload_length) +
                                QuicDataWriter::GetVarInt62Len(
                                    static_cast<uint64_t>(HttpFrameType::DATA));

  output->reset(new char[header_length]);
  QuicDataWriter writer(header_length, output->get());

  if (WriteFrameHeader(payload_length, HttpFrameType::DATA, &writer)) {
    return header_length;
  }
  QUIC_DLOG(ERROR)
      << "Http encoder failed when attempting to serialize data frame header.";
  return 0;
}

// static
QuicByteCount HttpEncoder::SerializeHeadersFrameHeader(
    QuicByteCount payload_length,
    std::unique_ptr<char[]>* output) {
  DCHECK_NE(0u, payload_length);
  QuicByteCount header_length =
      QuicDataWriter::GetVarInt62Len(payload_length) +
      QuicDataWriter::GetVarInt62Len(
          static_cast<uint64_t>(HttpFrameType::HEADERS));

  output->reset(new char[header_length]);
  QuicDataWriter writer(header_length, output->get());

  if (WriteFrameHeader(payload_length, HttpFrameType::HEADERS, &writer)) {
    return header_length;
  }
  QUIC_DLOG(ERROR)
      << "Http encoder failed when attempting to serialize headers "
         "frame header.";
  return 0;
}

// static
QuicByteCount HttpEncoder::SerializePriorityFrame(
    const PriorityFrame& priority,
    std::unique_ptr<char[]>* output) {
  QuicByteCount payload_length =
      kPriorityFirstByteLength +
      (priority.prioritized_type == ROOT_OF_TREE
           ? 0
           : QuicDataWriter::GetVarInt62Len(priority.prioritized_element_id)) +
      (priority.dependency_type == ROOT_OF_TREE
           ? 0
           : QuicDataWriter::GetVarInt62Len(priority.element_dependency_id)) +
      kPriorityWeightLength;
  QuicByteCount total_length =
      GetTotalLength(payload_length, HttpFrameType::PRIORITY);

  output->reset(new char[total_length]);
  QuicDataWriter writer(total_length, output->get());

  if (!WriteFrameHeader(payload_length, HttpFrameType::PRIORITY, &writer)) {
    QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
                        "priority frame header.";
    return 0;
  }

  // Set the first byte of the payload.
  uint8_t firstByte = 0;
  firstByte = SetPriorityFields(firstByte, priority.prioritized_type, true);
  firstByte = SetPriorityFields(firstByte, priority.dependency_type, false);
  if (priority.exclusive) {
    firstByte |= kPriorityExclusiveBit;
  }

  if (writer.WriteUInt8(firstByte) && MaybeWriteIds(priority, &writer) &&
      writer.WriteUInt8(priority.weight)) {
    return total_length;
  }
  QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
                      "priority frame payload.";
  return 0;
}

// static
QuicByteCount HttpEncoder::SerializeCancelPushFrame(
    const CancelPushFrame& cancel_push,
    std::unique_ptr<char[]>* output) {
  QuicByteCount payload_length =
      QuicDataWriter::GetVarInt62Len(cancel_push.push_id);
  QuicByteCount total_length =
      GetTotalLength(payload_length, HttpFrameType::CANCEL_PUSH);

  output->reset(new char[total_length]);
  QuicDataWriter writer(total_length, output->get());

  if (WriteFrameHeader(payload_length, HttpFrameType::CANCEL_PUSH, &writer) &&
      writer.WriteVarInt62(cancel_push.push_id)) {
    return total_length;
  }
  QUIC_DLOG(ERROR)
      << "Http encoder failed when attempting to serialize cancel push frame.";
  return 0;
}

// static
QuicByteCount HttpEncoder::SerializeSettingsFrame(
    const SettingsFrame& settings,
    std::unique_ptr<char[]>* output) {
  QuicByteCount payload_length = 0;
  // Calculate the payload length.
  for (auto it = settings.values.begin(); it != settings.values.end(); ++it) {
    payload_length += QuicDataWriter::GetVarInt62Len(it->first);
    payload_length += QuicDataWriter::GetVarInt62Len(it->second);
  }

  QuicByteCount total_length =
      GetTotalLength(payload_length, HttpFrameType::SETTINGS);

  output->reset(new char[total_length]);
  QuicDataWriter writer(total_length, output->get());

  if (!WriteFrameHeader(payload_length, HttpFrameType::SETTINGS, &writer)) {
    QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
                        "settings frame header.";
    return 0;
  }

  for (auto it = settings.values.begin(); it != settings.values.end(); ++it) {
    if (!writer.WriteVarInt62(it->first) || !writer.WriteVarInt62(it->second)) {
      QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
                          "settings frame payload.";
      return 0;
    }
  }

  return total_length;
}

// static
QuicByteCount HttpEncoder::SerializePushPromiseFrameWithOnlyPushId(
    const PushPromiseFrame& push_promise,
    std::unique_ptr<char[]>* output) {
  QuicByteCount payload_length =
      QuicDataWriter::GetVarInt62Len(push_promise.push_id) +
      push_promise.headers.length();
  // GetTotalLength() is not used because headers will not be serialized.
  QuicByteCount total_length =
      QuicDataWriter::GetVarInt62Len(payload_length) +
      QuicDataWriter::GetVarInt62Len(
          static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE)) +
      QuicDataWriter::GetVarInt62Len(push_promise.push_id);

  output->reset(new char[total_length]);
  QuicDataWriter writer(total_length, output->get());

  if (WriteFrameHeader(payload_length, HttpFrameType::PUSH_PROMISE, &writer) &&
      writer.WriteVarInt62(push_promise.push_id)) {
    return total_length;
  }
  QUIC_DLOG(ERROR)
      << "Http encoder failed when attempting to serialize push promise frame.";
  return 0;
}

// static
QuicByteCount HttpEncoder::SerializeGoAwayFrame(
    const GoAwayFrame& goaway,
    std::unique_ptr<char[]>* output) {
  QuicByteCount payload_length =
      QuicDataWriter::GetVarInt62Len(goaway.stream_id);
  QuicByteCount total_length =
      GetTotalLength(payload_length, HttpFrameType::GOAWAY);

  output->reset(new char[total_length]);
  QuicDataWriter writer(total_length, output->get());

  if (WriteFrameHeader(payload_length, HttpFrameType::GOAWAY, &writer) &&
      writer.WriteVarInt62(goaway.stream_id)) {
    return total_length;
  }
  QUIC_DLOG(ERROR)
      << "Http encoder failed when attempting to serialize goaway frame.";
  return 0;
}

// static
QuicByteCount HttpEncoder::SerializeMaxPushIdFrame(
    const MaxPushIdFrame& max_push_id,
    std::unique_ptr<char[]>* output) {
  QuicByteCount payload_length =
      QuicDataWriter::GetVarInt62Len(max_push_id.push_id);
  QuicByteCount total_length =
      GetTotalLength(payload_length, HttpFrameType::MAX_PUSH_ID);

  output->reset(new char[total_length]);
  QuicDataWriter writer(total_length, output->get());

  if (WriteFrameHeader(payload_length, HttpFrameType::MAX_PUSH_ID, &writer) &&
      writer.WriteVarInt62(max_push_id.push_id)) {
    return total_length;
  }
  QUIC_DLOG(ERROR)
      << "Http encoder failed when attempting to serialize max push id frame.";
  return 0;
}

// static
QuicByteCount HttpEncoder::SerializeDuplicatePushFrame(
    const DuplicatePushFrame& duplicate_push,
    std::unique_ptr<char[]>* output) {
  QuicByteCount payload_length =
      QuicDataWriter::GetVarInt62Len(duplicate_push.push_id);
  QuicByteCount total_length =
      GetTotalLength(payload_length, HttpFrameType::DUPLICATE_PUSH);

  output->reset(new char[total_length]);
  QuicDataWriter writer(total_length, output->get());

  if (WriteFrameHeader(payload_length, HttpFrameType::DUPLICATE_PUSH,
                       &writer) &&
      writer.WriteVarInt62(duplicate_push.push_id)) {
    return total_length;
  }
  QUIC_DLOG(ERROR) << "Http encoder failed when attempting to serialize "
                      "duplicate push frame.";
  return 0;
}

}  // namespace quic
