// 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/test_tools/quic_test_utils.h"

#include "base/stl_util.h"
#include "net/quic/crypto/crypto_framer.h"
#include "net/quic/crypto/crypto_handshake.h"
#include "net/quic/crypto/crypto_utils.h"
#include "net/quic/crypto/null_encrypter.h"
#include "net/quic/crypto/quic_decrypter.h"
#include "net/quic/crypto/quic_encrypter.h"
#include "net/quic/quic_framer.h"
#include "net/quic/quic_packet_creator.h"
#include "net/spdy/spdy_frame_builder.h"

using base::StringPiece;
using std::max;
using std::min;
using std::string;
using testing::_;

namespace net {
namespace test {
namespace {

// No-op alarm implementation used by MockHelper.
class TestAlarm : public QuicAlarm {
 public:
  explicit TestAlarm(QuicAlarm::Delegate* delegate)
      : QuicAlarm(delegate) {
  }

  virtual void SetImpl() OVERRIDE {}
  virtual void CancelImpl() OVERRIDE {}
};

}  // namespace

MockFramerVisitor::MockFramerVisitor() {
  // By default, we want to accept packets.
  ON_CALL(*this, OnProtocolVersionMismatch(_))
      .WillByDefault(testing::Return(false));

  // By default, we want to accept packets.
  ON_CALL(*this, OnPacketHeader(_))
      .WillByDefault(testing::Return(true));

  ON_CALL(*this, OnStreamFrame(_))
      .WillByDefault(testing::Return(true));

  ON_CALL(*this, OnAckFrame(_))
      .WillByDefault(testing::Return(true));

  ON_CALL(*this, OnCongestionFeedbackFrame(_))
      .WillByDefault(testing::Return(true));

  ON_CALL(*this, OnRstStreamFrame(_))
      .WillByDefault(testing::Return(true));

  ON_CALL(*this, OnConnectionCloseFrame(_))
      .WillByDefault(testing::Return(true));

  ON_CALL(*this, OnGoAwayFrame(_))
      .WillByDefault(testing::Return(true));
}

MockFramerVisitor::~MockFramerVisitor() {
}

bool NoOpFramerVisitor::OnProtocolVersionMismatch(QuicVersion version) {
  return false;
}

bool NoOpFramerVisitor::OnPacketHeader(const QuicPacketHeader& header) {
  return true;
}

bool NoOpFramerVisitor::OnStreamFrame(const QuicStreamFrame& frame) {
  return true;
}

bool NoOpFramerVisitor::OnAckFrame(const QuicAckFrame& frame) {
  return true;
}

bool NoOpFramerVisitor::OnCongestionFeedbackFrame(
    const QuicCongestionFeedbackFrame& frame) {
  return true;
}

bool NoOpFramerVisitor::OnRstStreamFrame(
    const QuicRstStreamFrame& frame) {
  return true;
}

bool NoOpFramerVisitor::OnConnectionCloseFrame(
    const QuicConnectionCloseFrame& frame) {
  return true;
}

bool NoOpFramerVisitor::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
  return true;
}

FramerVisitorCapturingFrames::FramerVisitorCapturingFrames() : frame_count_(0) {
}

FramerVisitorCapturingFrames::~FramerVisitorCapturingFrames() {
}

bool FramerVisitorCapturingFrames::OnPacketHeader(
    const QuicPacketHeader& header) {
  header_ = header;
  frame_count_ = 0;
  return true;
}

bool FramerVisitorCapturingFrames::OnStreamFrame(const QuicStreamFrame& frame) {
  // TODO(ianswett): Own the underlying string, so it will not exist outside
  // this callback.
  stream_frames_.push_back(frame);
  ++frame_count_;
  return true;
}

bool FramerVisitorCapturingFrames::OnAckFrame(const QuicAckFrame& frame) {
  ack_.reset(new QuicAckFrame(frame));
  ++frame_count_;
  return true;
}

bool FramerVisitorCapturingFrames::OnCongestionFeedbackFrame(
    const QuicCongestionFeedbackFrame& frame) {
  feedback_.reset(new QuicCongestionFeedbackFrame(frame));
  ++frame_count_;
  return true;
}

bool FramerVisitorCapturingFrames::OnRstStreamFrame(
    const QuicRstStreamFrame& frame) {
  rst_.reset(new QuicRstStreamFrame(frame));
  ++frame_count_;
  return true;
}

bool FramerVisitorCapturingFrames::OnConnectionCloseFrame(
    const QuicConnectionCloseFrame& frame) {
  close_.reset(new QuicConnectionCloseFrame(frame));
  ++frame_count_;
  return true;
}

bool FramerVisitorCapturingFrames::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
  goaway_.reset(new QuicGoAwayFrame(frame));
  ++frame_count_;
  return true;
}

void FramerVisitorCapturingFrames::OnVersionNegotiationPacket(
    const QuicVersionNegotiationPacket& packet) {
  version_negotiation_packet_.reset(new QuicVersionNegotiationPacket(packet));
  frame_count_ = 0;
}

FramerVisitorCapturingPublicReset::FramerVisitorCapturingPublicReset() {
}

FramerVisitorCapturingPublicReset::~FramerVisitorCapturingPublicReset() {
}

void FramerVisitorCapturingPublicReset::OnPublicResetPacket(
    const QuicPublicResetPacket& public_reset) {
  public_reset_packet_ = public_reset;
}

MockConnectionVisitor::MockConnectionVisitor() {
}

MockConnectionVisitor::~MockConnectionVisitor() {
}

MockHelper::MockHelper() {
}

MockHelper::~MockHelper() {
}

const QuicClock* MockHelper::GetClock() const {
  return &clock_;
}

QuicRandom* MockHelper::GetRandomGenerator() {
  return &random_generator_;
}

QuicAlarm* MockHelper::CreateAlarm(QuicAlarm::Delegate* delegate) {
  return new TestAlarm(delegate);
}

void MockHelper::AdvanceTime(QuicTime::Delta delta) {
  clock_.AdvanceTime(delta);
}

MockConnection::MockConnection(QuicGuid guid,
                               IPEndPoint address,
                               bool is_server)
    : QuicConnection(guid, address, new testing::NiceMock<MockHelper>(),
                     is_server, QuicVersionMax()),
      has_mock_helper_(true) {
}

MockConnection::MockConnection(QuicGuid guid,
                               IPEndPoint address,
                               QuicConnectionHelperInterface* helper,
                               bool is_server)
    : QuicConnection(guid, address, helper, is_server, QuicVersionMax()),
      has_mock_helper_(false) {
}

MockConnection::~MockConnection() {
}

void MockConnection::AdvanceTime(QuicTime::Delta delta) {
  CHECK(has_mock_helper_) << "Cannot advance time unless a MockClock is being"
                             " used";
  static_cast<MockHelper*>(helper())->AdvanceTime(delta);
}

PacketSavingConnection::PacketSavingConnection(QuicGuid guid,
                                               IPEndPoint address,
                                               bool is_server)
    : MockConnection(guid, address, is_server) {
}

PacketSavingConnection::~PacketSavingConnection() {
  STLDeleteElements(&packets_);
  STLDeleteElements(&encrypted_packets_);
}

bool PacketSavingConnection::SendOrQueuePacket(
    EncryptionLevel level,
    QuicPacketSequenceNumber sequence_number,
    QuicPacket* packet,
    QuicPacketEntropyHash entropy_hash,
    HasRetransmittableData retransmittable) {
  packets_.push_back(packet);
  QuicEncryptedPacket* encrypted =
      framer_.EncryptPacket(level, sequence_number, *packet);
  encrypted_packets_.push_back(encrypted);
  return true;
}

MockSession::MockSession(QuicConnection* connection, bool is_server)
    : QuicSession(connection, DefaultQuicConfig(), is_server) {
  ON_CALL(*this, WriteData(_, _, _, _))
      .WillByDefault(testing::Return(QuicConsumedData(0, false)));
}

MockSession::~MockSession() {
}

TestSession::TestSession(QuicConnection* connection,
                         const QuicConfig& config,
                         bool is_server)
    : QuicSession(connection, config, is_server),
      crypto_stream_(NULL) {
}

TestSession::~TestSession() {}

void TestSession::SetCryptoStream(QuicCryptoStream* stream) {
  crypto_stream_ = stream;
}

QuicCryptoStream* TestSession::GetCryptoStream() {
  return crypto_stream_;
}

MockSendAlgorithm::MockSendAlgorithm() {
}

MockSendAlgorithm::~MockSendAlgorithm() {
}

namespace {

string HexDumpWithMarks(const char* data, int length,
                        const bool* marks, int mark_length) {
  static const char kHexChars[] = "0123456789abcdef";
  static const int kColumns = 4;

  const int kSizeLimit = 1024;
  if (length > kSizeLimit || mark_length > kSizeLimit) {
    LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes.";
    length = min(length, kSizeLimit);
    mark_length = min(mark_length, kSizeLimit);
  }

  string hex;
  for (const char* row = data; length > 0;
       row += kColumns, length -= kColumns) {
    for (const char *p = row; p < row + 4; ++p) {
      if (p < row + length) {
        const bool mark =
            (marks && (p - data) < mark_length && marks[p - data]);
        hex += mark ? '*' : ' ';
        hex += kHexChars[(*p & 0xf0) >> 4];
        hex += kHexChars[*p & 0x0f];
        hex += mark ? '*' : ' ';
      } else {
        hex += "    ";
      }
    }
    hex = hex + "  ";

    for (const char *p = row; p < row + 4 && p < row + length; ++p)
      hex += (*p >= 0x20 && *p <= 0x7f) ? (*p) : '.';

    hex = hex + '\n';
  }
  return hex;
}

}  // namespace

void CompareCharArraysWithHexError(
    const string& description,
    const char* actual,
    const int actual_len,
    const char* expected,
    const int expected_len) {
  const int min_len = min(actual_len, expected_len);
  const int max_len = max(actual_len, expected_len);
  scoped_ptr<bool[]> marks(new bool[max_len]);
  bool identical = (actual_len == expected_len);
  for (int i = 0; i < min_len; ++i) {
    if (actual[i] != expected[i]) {
      marks[i] = true;
      identical = false;
    } else {
      marks[i] = false;
    }
  }
  for (int i = min_len; i < max_len; ++i) {
    marks[i] = true;
  }
  if (identical) return;
  ADD_FAILURE()
      << "Description:\n"
      << description
      << "\n\nExpected:\n"
      << HexDumpWithMarks(expected, expected_len, marks.get(), max_len)
      << "\nActual:\n"
      << HexDumpWithMarks(actual, actual_len, marks.get(), max_len);
}

void CompareQuicDataWithHexError(
    const string& description,
    QuicData* actual,
    QuicData* expected) {
  CompareCharArraysWithHexError(
      description,
      actual->data(), actual->length(),
      expected->data(), expected->length());
}

static QuicPacket* ConstructPacketFromHandshakeMessage(
    QuicGuid guid,
    const CryptoHandshakeMessage& message,
    bool should_include_version) {
  CryptoFramer crypto_framer;
  scoped_ptr<QuicData> data(crypto_framer.ConstructHandshakeMessage(message));
  QuicFramer quic_framer(QuicVersionMax(), QuicTime::Zero(), false);

  QuicPacketHeader header;
  header.public_header.guid = guid;
  header.public_header.reset_flag = false;
  header.public_header.version_flag = should_include_version;
  header.packet_sequence_number = 1;
  header.entropy_flag = false;
  header.entropy_hash = 0;
  header.fec_flag = false;
  header.fec_group = 0;

  QuicStreamFrame stream_frame(kCryptoStreamId, false, 0,
                               data->AsStringPiece());

  QuicFrame frame(&stream_frame);
  QuicFrames frames;
  frames.push_back(frame);
  return quic_framer.BuildUnsizedDataPacket(header, frames).packet;
}

QuicPacket* ConstructHandshakePacket(QuicGuid guid, QuicTag tag) {
  CryptoHandshakeMessage message;
  message.set_tag(tag);
  return ConstructPacketFromHandshakeMessage(guid, message, false);
}

size_t GetPacketLengthForOneStream(QuicVersion version,
                                   bool include_version,
                                   InFecGroup is_in_fec_group,
                                   size_t* payload_length) {
  *payload_length = 1;
  const size_t stream_length =
      NullEncrypter().GetCiphertextSize(*payload_length) +
      QuicPacketCreator::StreamFramePacketOverhead(
          version, PACKET_8BYTE_GUID, include_version,
          PACKET_6BYTE_SEQUENCE_NUMBER, is_in_fec_group);
  const size_t ack_length = NullEncrypter().GetCiphertextSize(
      QuicFramer::GetMinAckFrameSize()) +
      GetPacketHeaderSize(PACKET_8BYTE_GUID, include_version,
                          PACKET_6BYTE_SEQUENCE_NUMBER, is_in_fec_group);
  if (stream_length < ack_length) {
    *payload_length = 1 + ack_length - stream_length;
  }

  return NullEncrypter().GetCiphertextSize(*payload_length) +
      QuicPacketCreator::StreamFramePacketOverhead(
          version, PACKET_8BYTE_GUID, include_version,
          PACKET_6BYTE_SEQUENCE_NUMBER, is_in_fec_group);
}

size_t GetMinStreamFrameSize(QuicVersion version) {
  return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize +
      (version == QUIC_VERSION_6 ?
          (kQuicStreamFinSize + kQuicStreamPayloadLengthSize) : 0);
}

QuicPacketEntropyHash TestEntropyCalculator::EntropyHash(
    QuicPacketSequenceNumber sequence_number) const {
  return 1u;
}

QuicConfig DefaultQuicConfig() {
  QuicConfig config;
  config.SetDefaults();
  return config;
}

bool TestDecompressorVisitor::OnDecompressedData(StringPiece data) {
  data.AppendToString(&data_);
  return true;
}

void TestDecompressorVisitor::OnDecompressionError() {
  error_ = true;
}

}  // namespace test
}  // namespace net
