// 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"

namespace quic {

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

void QpackInstructionEncoder::Encode(const QpackInstruction* instruction,
                                     const Values& values,
                                     std::string* output) {
  DCHECK(instruction);

  state_ = State::kOpcode;
  instruction_ = 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(values.s_bit);
        break;
      case State::kVarintEncode:
        DoVarintEncode(values.varint, values.varint2, output);
        break;
      case State::kStartString:
        DoStartString(values.name, 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(QuicStringPiece name,
                                            QuicStringPiece value) {
  DCHECK(field_->type == QpackInstructionFieldType::kName ||
         field_->type == QpackInstructionFieldType::kValue);

  string_to_write_ =
      (field_->type == QpackInstructionFieldType::kName) ? name : value;
  http2::HuffmanEncode(string_to_write_, &huffman_encoded_string_);

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

    byte_ |= (1 << field_->param);
    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
