#include "spdy/core/metadata_extension.h"

#include <list>
#include <string>

#include "absl/memory/memory.h"
#include "absl/strings/str_cat.h"
#include "http2/decoder/decode_buffer.h"
#include "http2/hpack/decoder/hpack_decoder.h"
#include "common/platform/api/quiche_bug_tracker.h"
#include "common/platform/api/quiche_logging.h"
#include "spdy/core/hpack/hpack_encoder.h"
#include "spdy/core/http2_header_block_hpack_listener.h"

namespace spdy {

// Non-standard constants related to METADATA frames.
const SpdySettingsId MetadataVisitor::kMetadataExtensionId = 0x4d44;
const uint8_t MetadataVisitor::kMetadataFrameType = 0x4d;
const uint8_t MetadataVisitor::kEndMetadataFlag = 0x4;

namespace {

const size_t kMaxMetadataBlockSize = 1 << 20;  // 1 MB

// This class uses an HpackEncoder to serialize a METADATA block as a series of
// METADATA frames.
class MetadataFrameSequence : public MetadataSerializer::FrameSequence {
 public:
  MetadataFrameSequence(SpdyStreamId stream_id, spdy::SpdyHeaderBlock payload)
      : stream_id_(stream_id), payload_(std::move(payload)) {
    // Metadata should not use HPACK compression.
    encoder_.DisableCompression();
    HpackEncoder::Representations r;
    for (const auto& kv_pair : payload_) {
      r.push_back(kv_pair);
    }
    progressive_encoder_ = encoder_.EncodeRepresentations(r);
  }

  // Copies are not allowed.
  MetadataFrameSequence(const MetadataFrameSequence& other) = delete;
  MetadataFrameSequence& operator=(const MetadataFrameSequence& other) = delete;

  std::unique_ptr<spdy::SpdyFrameIR> Next() override;

 private:
  SpdyStreamId stream_id_;
  SpdyHeaderBlock payload_;
  HpackEncoder encoder_;
  std::unique_ptr<HpackEncoder::ProgressiveEncoder> progressive_encoder_;
};

std::unique_ptr<spdy::SpdyFrameIR> MetadataFrameSequence::Next() {
  if (!progressive_encoder_->HasNext()) {
    return nullptr;
  }
  std::string payload;
  // METADATA frames obey the HTTP/2 maximum frame size.
  progressive_encoder_->Next(spdy::kHttp2DefaultFramePayloadLimit, &payload);
  const bool end_metadata = (!progressive_encoder_->HasNext());
  const uint8_t flags = end_metadata ? MetadataVisitor::kEndMetadataFlag : 0;
  return absl::make_unique<spdy::SpdyUnknownIR>(
      stream_id_, MetadataVisitor::kMetadataFrameType, flags,
      std::move(payload));
}

}  // anonymous namespace

struct MetadataVisitor::MetadataPayloadState {
  MetadataPayloadState(size_t remaining, bool end)
      : bytes_remaining(remaining), end_metadata(end) {}
  std::list<std::string> buffer;
  size_t bytes_remaining;
  bool end_metadata;
};

MetadataVisitor::MetadataVisitor(OnCompletePayload on_payload,
                                 OnMetadataSupport on_support)
    : on_payload_(std::move(on_payload)),
      on_support_(std::move(on_support)),
      peer_supports_metadata_(MetadataSupportState::UNSPECIFIED) {}

MetadataVisitor::~MetadataVisitor() {}

void MetadataVisitor::OnSetting(SpdySettingsId id, uint32_t value) {
  QUICHE_VLOG(1) << "MetadataVisitor::OnSetting(" << id << ", " << value << ")";
  if (id == kMetadataExtensionId) {
    if (value == 0) {
      const MetadataSupportState previous_state = peer_supports_metadata_;
      peer_supports_metadata_ = MetadataSupportState::NOT_SUPPORTED;
      if (previous_state == MetadataSupportState::UNSPECIFIED ||
          previous_state == MetadataSupportState::SUPPORTED) {
        on_support_(false);
      }
    } else if (value == 1) {
      const MetadataSupportState previous_state = peer_supports_metadata_;
      peer_supports_metadata_ = MetadataSupportState::SUPPORTED;
      if (previous_state == MetadataSupportState::UNSPECIFIED ||
          previous_state == MetadataSupportState::NOT_SUPPORTED) {
        on_support_(true);
      }
    } else {
      LOG_EVERY_N_SEC(WARNING, 1)
          << "Unrecognized value for setting " << id << ": " << value;
    }
  }
}

bool MetadataVisitor::OnFrameHeader(SpdyStreamId stream_id, size_t length,
                                    uint8_t type, uint8_t flags) {
  QUICHE_VLOG(1) << "OnFrameHeader(stream_id=" << stream_id
                 << ", length=" << length << ", type=" << static_cast<int>(type)
                 << ", flags=" << static_cast<int>(flags);
  // TODO(birenroy): Consider disabling METADATA handling until our setting
  // advertising METADATA support has been acked.
  if (type != kMetadataFrameType) {
    return false;
  }
  auto it = metadata_map_.find(stream_id);
  if (it == metadata_map_.end()) {
    auto state = absl::make_unique<MetadataPayloadState>(
        length, flags & kEndMetadataFlag);
    auto result = metadata_map_.insert(std::make_pair(stream_id,
                                                      std::move(state)));
    QUICHE_BUG_IF(bug_if_2781_1, !result.second) << "Map insertion failed.";
    it = result.first;
  } else {
    QUICHE_BUG_IF(bug_22051_1, it->second->end_metadata)
        << "Inconsistent metadata payload state!";
    QUICHE_BUG_IF(bug_if_2781_2, it->second->bytes_remaining > 0)
        << "Incomplete metadata block!";
  }

  if (it->second == nullptr) {
    QUICHE_BUG(bug_2781_3) << "Null metadata payload state!";
    return false;
  }
  current_stream_ = stream_id;
  it->second->bytes_remaining = length;
  it->second->end_metadata = (flags & kEndMetadataFlag);
  return true;
}

void MetadataVisitor::OnFramePayload(const char* data, size_t len) {
  QUICHE_VLOG(1) << "OnFramePayload(stream_id=" << current_stream_
                 << ", len=" << len << ")";
  auto it = metadata_map_.find(current_stream_);
  if (it == metadata_map_.end() || it->second == nullptr) {
    QUICHE_BUG(bug_2781_4) << "Invalid order of operations on MetadataVisitor.";
  } else {
    MetadataPayloadState* state = it->second.get();  // For readability.
    state->buffer.push_back(std::string(data, len));
    if (len < state->bytes_remaining) {
      state->bytes_remaining -= len;
    } else {
      QUICHE_BUG_IF(bug_22051_2, len > state->bytes_remaining)
          << "Metadata payload overflow! len: " << len
          << " bytes_remaining: " << state->bytes_remaining;
      state->bytes_remaining = 0;
      if (state->end_metadata) {
        // The whole process of decoding the HPACK-encoded metadata block,
        // below, is more cumbersome than it ought to be.
        spdy::Http2HeaderBlockHpackListener listener;
        http2::HpackDecoder decoder(&listener, kMaxMetadataBlockSize);

        // If any operations fail, the decode process should be aborted.
        bool success = decoder.StartDecodingBlock();
        for (const std::string& slice : state->buffer) {
          if (!success) {
            break;
          }
          http2::DecodeBuffer buffer(slice.data(), slice.size());
          success = success && decoder.DecodeFragment(&buffer);
        }
        success =
            success && decoder.EndDecodingBlock() && !listener.hpack_error();
        if (success) {
          on_payload_(current_stream_, listener.release_header_block());
        }
        // TODO(birenroy): add varz counting metadata decode successes/failures.
        metadata_map_.erase(it);
      }
    }
  }
}

std::unique_ptr<MetadataSerializer::FrameSequence>
MetadataSerializer::FrameSequenceForPayload(SpdyStreamId stream_id,
                                            MetadataPayload payload) {
  return absl::make_unique<MetadataFrameSequence>(stream_id,
                                                  std::move(payload));
}

}  // namespace spdy
