// Copyright (c) 2012 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/quic/quic_crypto_stream.h"

#include <string>

#include "base/strings/string_piece.h"
#include "net/quic/crypto/crypto_handshake.h"
#include "net/quic/crypto/crypto_utils.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_session.h"
#include "net/quic/quic_utils.h"

using std::string;
using base::StringPiece;

namespace net {

#define ENDPOINT (session()->is_server() ? "Server: " : " Client: ")

QuicCryptoStream::QuicCryptoStream(QuicSession* session)
    : ReliableQuicStream(kCryptoStreamId, session),
      encryption_established_(false),
      handshake_confirmed_(false) {
  crypto_framer_.set_visitor(this);
  if (version() < QUIC_VERSION_21) {
    // Prior to QUIC_VERSION_21 the crypto stream is not subject to any flow
    // control.
    DisableFlowControl();
  }
  // The crypto stream is exempt from connection level flow control.
  DisableConnectionFlowControlForThisStream();
}

void QuicCryptoStream::OnError(CryptoFramer* framer) {
  DLOG(WARNING) << "Error processing crypto data: "
                << QuicUtils::ErrorToString(framer->error());
}

void QuicCryptoStream::OnHandshakeMessage(
    const CryptoHandshakeMessage& message) {
  DVLOG(1) << ENDPOINT << "Received " << message.DebugString();
  session()->OnCryptoHandshakeMessageReceived(message);
}

uint32 QuicCryptoStream::ProcessRawData(const char* data,
                                        uint32 data_len) {
  if (!crypto_framer_.ProcessInput(StringPiece(data, data_len))) {
    CloseConnection(crypto_framer_.error());
    return 0;
  }
  return data_len;
}

QuicPriority QuicCryptoStream::EffectivePriority() const {
  return QuicUtils::HighestPriority();
}

void QuicCryptoStream::SendHandshakeMessage(
    const CryptoHandshakeMessage& message) {
  SendHandshakeMessage(message, nullptr);
}

void QuicCryptoStream::SendHandshakeMessage(
    const CryptoHandshakeMessage& message,
    QuicAckNotifier::DelegateInterface* delegate) {
  DVLOG(1) << ENDPOINT << "Sending " << message.DebugString();
  session()->OnCryptoHandshakeMessageSent(message);
  const QuicData& data = message.GetSerialized();
  // TODO(wtc): check the return value.
  WriteOrBufferData(string(data.data(), data.length()), false, delegate);
}

bool QuicCryptoStream::ExportKeyingMaterial(
    StringPiece label,
    StringPiece context,
    size_t result_len,
    string* result) const {
  if (!handshake_confirmed()) {
    DLOG(ERROR) << "ExportKeyingMaterial was called before forward-secure"
                << "encryption was established.";
    return false;
  }
  return CryptoUtils::ExportKeyingMaterial(
      crypto_negotiated_params_.subkey_secret,
      label,
      context,
      result_len,
      result);
}

const QuicCryptoNegotiatedParameters&
QuicCryptoStream::crypto_negotiated_params() const {
  return crypto_negotiated_params_;
}

}  // namespace net
