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

#include "absl/strings/string_view.h"
#include "http2/decoder/decode_buffer.h"
#include "http2/decoder/decode_status.h"
#include "quic/core/qpack/qpack_instructions.h"
#include "quic/platform/api/quic_logging.h"

namespace quic {

QpackEncoderStreamReceiver::QpackEncoderStreamReceiver(Delegate* delegate)
    : instruction_decoder_(QpackEncoderStreamLanguage(), this),
      delegate_(delegate),
      error_detected_(false) {
  QUICHE_DCHECK(delegate_);
}

void QpackEncoderStreamReceiver::Decode(absl::string_view data) {
  if (data.empty() || error_detected_) {
    return;
  }

  instruction_decoder_.Decode(data);
}

bool QpackEncoderStreamReceiver::OnInstructionDecoded(
    const QpackInstruction* instruction) {
  if (instruction == InsertWithNameReferenceInstruction()) {
    delegate_->OnInsertWithNameReference(instruction_decoder_.s_bit(),
                                         instruction_decoder_.varint(),
                                         instruction_decoder_.value());
    return true;
  }

  if (instruction == InsertWithoutNameReferenceInstruction()) {
    delegate_->OnInsertWithoutNameReference(instruction_decoder_.name(),
                                            instruction_decoder_.value());
    return true;
  }

  if (instruction == DuplicateInstruction()) {
    delegate_->OnDuplicate(instruction_decoder_.varint());
    return true;
  }

  QUICHE_DCHECK_EQ(instruction, SetDynamicTableCapacityInstruction());
  delegate_->OnSetDynamicTableCapacity(instruction_decoder_.varint());
  return true;
}

void QpackEncoderStreamReceiver::OnInstructionDecodingError(
    QpackInstructionDecoder::ErrorCode error_code,
    absl::string_view error_message) {
  QUICHE_DCHECK(!error_detected_);

  error_detected_ = true;

  QuicErrorCode quic_error_code;
  switch (error_code) {
    case QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE:
      quic_error_code = QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE;
      break;
    case QpackInstructionDecoder::ErrorCode::STRING_LITERAL_TOO_LONG:
      quic_error_code = QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG;
      break;
    case QpackInstructionDecoder::ErrorCode::HUFFMAN_ENCODING_ERROR:
      quic_error_code = QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR;
      break;
    default:
      quic_error_code = QUIC_INTERNAL_ERROR;
  }

  delegate_->OnErrorDetected(quic_error_code, error_message);
}

}  // namespace quic
