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

#include <limits>

#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "http2/hpack/huffman/hpack_huffman_encoder.h"
#include "http2/hpack/varint/hpack_varint_encoder.h"
#include "quic/platform/api/quic_flags.h"
#include "quic/platform/api/quic_logging.h"

namespace quic {

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

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

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

  // Field list must not be empty.
  QUICHE_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(instruction_with_values.name(),
                      instruction_with_values.value(), output);
        break;
    }
  } while (field_ != instruction_->fields.end());

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

void QpackInstructionEncoder::DoOpcode() {
  QUICHE_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) {
  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kSbit);

  if (s_bit) {
    QUICHE_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) {
  QUICHE_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_length_;
      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(absl::string_view name,
                                            absl::string_view value) {
  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
                field_->type == QpackInstructionFieldType::kValue);

  absl::string_view string_to_write =
      (field_->type == QpackInstructionFieldType::kName) ? name : value;
  string_length_ = string_to_write.size();

  size_t encoded_size = http2::HuffmanSize(string_to_write);
  use_huffman_ = encoded_size < string_length_;

  if (use_huffman_) {
    QUICHE_DCHECK_EQ(0, byte_ & (1 << field_->param));
    byte_ |= (1 << field_->param);

    string_length_ = encoded_size;
  }

  state_ = State::kVarintEncode;
}

void QpackInstructionEncoder::DoWriteString(absl::string_view name,
                                            absl::string_view value,
                                            std::string* output) {
  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
                field_->type == QpackInstructionFieldType::kValue);

  absl::string_view string_to_write =
      (field_->type == QpackInstructionFieldType::kName) ? name : value;
  if (use_huffman_) {
    http2::HuffmanEncodeFast(string_to_write, string_length_, output);
  } else {
    absl::StrAppend(output, string_to_write);
  }

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

}  // namespace quic
