// Copyright 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/qpack/qpack_instruction_encoder.h"

#include <limits>

#include "net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder.h"
#include "net/third_party/quiche/src/http2/hpack/varint/hpack_varint_encoder.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_string_utils.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"

namespace quic {

QpackInstructionEncoder::QpackInstructionEncoder()
    : byte_(0), state_(State::kOpcode), instruction_(nullptr) {}

void QpackInstructionEncoder::Encode(
    const QpackInstructionWithValues& instruction_with_values,
    std::string* output) {
  DCHECK(instruction_with_values.instruction());

  state_ = State::kOpcode;
  instruction_ = instruction_with_values.instruction();
  field_ = instruction_->fields.begin();

  // Field list must not be empty.
  DCHECK(field_ != instruction_->fields.end());

  do {
    switch (state_) {
      case State::kOpcode:
        DoOpcode();
        break;
      case State::kStartField:
        DoStartField();
        break;
      case State::kSbit:
        DoSBit(instruction_with_values.s_bit());
        break;
      case State::kVarintEncode:
        DoVarintEncode(instruction_with_values.varint(),
                       instruction_with_values.varint2(), output);
        break;
      case State::kStartString:
        DoStartString(instruction_with_values.name(),
                      instruction_with_values.value());
        break;
      case State::kWriteString:
        DoWriteString(output);
        break;
    }
  } while (field_ != instruction_->fields.end());

  DCHECK(state_ == State::kStartField);
}

void QpackInstructionEncoder::DoOpcode() {
  DCHECK_EQ(0u, byte_);

  byte_ = instruction_->opcode.value;

  state_ = State::kStartField;
}

void QpackInstructionEncoder::DoStartField() {
  switch (field_->type) {
    case QpackInstructionFieldType::kSbit:
      state_ = State::kSbit;
      return;
    case QpackInstructionFieldType::kVarint:
    case QpackInstructionFieldType::kVarint2:
      state_ = State::kVarintEncode;
      return;
    case QpackInstructionFieldType::kName:
    case QpackInstructionFieldType::kValue:
      state_ = State::kStartString;
      return;
  }
}

void QpackInstructionEncoder::DoSBit(bool s_bit) {
  DCHECK(field_->type == QpackInstructionFieldType::kSbit);

  if (s_bit) {
    DCHECK_EQ(0, byte_ & field_->param);

    byte_ |= field_->param;
  }

  ++field_;
  state_ = State::kStartField;
}

void QpackInstructionEncoder::DoVarintEncode(uint64_t varint,
                                             uint64_t varint2,
                                             std::string* output) {
  DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
         field_->type == QpackInstructionFieldType::kVarint2 ||
         field_->type == QpackInstructionFieldType::kName ||
         field_->type == QpackInstructionFieldType::kValue);
  uint64_t integer_to_encode;
  switch (field_->type) {
    case QpackInstructionFieldType::kVarint:
      integer_to_encode = varint;
      break;
    case QpackInstructionFieldType::kVarint2:
      integer_to_encode = varint2;
      break;
    default:
      integer_to_encode = string_to_write_.size();
      break;
  }

  http2::HpackVarintEncoder::Encode(byte_, field_->param, integer_to_encode,
                                    output);
  byte_ = 0;

  if (field_->type == QpackInstructionFieldType::kVarint ||
      field_->type == QpackInstructionFieldType::kVarint2) {
    ++field_;
    state_ = State::kStartField;
    return;
  }

  state_ = State::kWriteString;
}

void QpackInstructionEncoder::DoStartString(quiche::QuicheStringPiece name,
                                            quiche::QuicheStringPiece value) {
  DCHECK(field_->type == QpackInstructionFieldType::kName ||
         field_->type == QpackInstructionFieldType::kValue);

  string_to_write_ =
      (field_->type == QpackInstructionFieldType::kName) ? name : value;
  size_t encoded_size = http2::HuffmanSize(string_to_write_);

  if (encoded_size < string_to_write_.size()) {
    DCHECK_EQ(0, byte_ & (1 << field_->param));
    byte_ |= (1 << field_->param);

    http2::HuffmanEncode(string_to_write_, encoded_size,
                         &huffman_encoded_string_);
    string_to_write_ = huffman_encoded_string_;
  }

  state_ = State::kVarintEncode;
}

void QpackInstructionEncoder::DoWriteString(std::string* output) {
  DCHECK(field_->type == QpackInstructionFieldType::kName ||
         field_->type == QpackInstructionFieldType::kValue);

  QuicStrAppend(output, string_to_write_);

  ++field_;
  state_ = State::kStartField;
}

}  // namespace quic
