// 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 "net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_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()
    : s_bit_(false),
      varint_(0),
      varint2_(0),
      byte_(0),
      state_(State::kOpcode),
      instruction_(nullptr) {}

void QpackInstructionEncoder::Encode(const QpackInstruction* instruction) {
  DCHECK(!HasNext());

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

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

bool QpackInstructionEncoder::HasNext() const {
  return instruction_ && (field_ != instruction_->fields.end());
}

void QpackInstructionEncoder::Next(size_t max_encoded_bytes,
                                   std::string* output) {
  DCHECK(HasNext());
  DCHECK_NE(0u, max_encoded_bytes);

  while (max_encoded_bytes > 0 && HasNext()) {
    size_t encoded_bytes = 0;

    switch (state_) {
      case State::kOpcode:
        DoOpcode();
        break;
      case State::kStartField:
        DoStartField();
        break;
      case State::kSbit:
        DoStaticBit();
        break;
      case State::kVarintStart:
        encoded_bytes = DoVarintStart(max_encoded_bytes, output);
        break;
      case State::kVarintResume:
        encoded_bytes = DoVarintResume(max_encoded_bytes, output);
        break;
      case State::kStartString:
        DoStartString();
        break;
      case State::kWriteString:
        encoded_bytes = DoWriteString(max_encoded_bytes, output);
        break;
    }

    DCHECK_LE(encoded_bytes, max_encoded_bytes);
    max_encoded_bytes -= encoded_bytes;
  }
}

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::kVarintStart;
      return;
    case QpackInstructionFieldType::kName:
    case QpackInstructionFieldType::kValue:
      state_ = State::kStartString;
      return;
  }
}

void QpackInstructionEncoder::DoStaticBit() {
  DCHECK(field_->type == QpackInstructionFieldType::kSbit);

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

    byte_ |= field_->param;
  }

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

size_t QpackInstructionEncoder::DoVarintStart(size_t max_encoded_bytes,
                                              std::string* output) {
  DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
         field_->type == QpackInstructionFieldType::kVarint2 ||
         field_->type == QpackInstructionFieldType::kName ||
         field_->type == QpackInstructionFieldType::kValue);
  DCHECK(!varint_encoder_.IsEncodingInProgress());

  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;
  }

  output->push_back(
      varint_encoder_.StartEncoding(byte_, field_->param, integer_to_encode));
  byte_ = 0;

  if (varint_encoder_.IsEncodingInProgress()) {
    state_ = State::kVarintResume;
    return 1;
  }

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

  state_ = State::kWriteString;
  return 1;
}

size_t QpackInstructionEncoder::DoVarintResume(size_t max_encoded_bytes,
                                               std::string* output) {
  DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
         field_->type == QpackInstructionFieldType::kVarint2 ||
         field_->type == QpackInstructionFieldType::kName ||
         field_->type == QpackInstructionFieldType::kValue);
  DCHECK(varint_encoder_.IsEncodingInProgress());

  const size_t encoded_bytes =
      varint_encoder_.ResumeEncoding(max_encoded_bytes, output);
  if (varint_encoder_.IsEncodingInProgress()) {
    DCHECK_EQ(encoded_bytes, max_encoded_bytes);
    return encoded_bytes;
  }

  DCHECK_LE(encoded_bytes, max_encoded_bytes);

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

  state_ = State::kWriteString;
  return encoded_bytes;
}

void QpackInstructionEncoder::DoStartString() {
  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::kVarintStart;
}

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

  if (max_encoded_bytes < string_to_write_.size()) {
    const size_t encoded_bytes = max_encoded_bytes;
    QuicStrAppend(output, string_to_write_.substr(0, encoded_bytes));
    string_to_write_ = string_to_write_.substr(encoded_bytes);
    return encoded_bytes;
  }

  const size_t encoded_bytes = string_to_write_.size();
  QuicStrAppend(output, string_to_write_);

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

}  // namespace quic
