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

#include <set>
#include <vector>

#include "base/containers/hash_tables.h"
#include "net/quic/crypto/crypto_handshake.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/test_tools/quic_connection_peer.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/quic/test_tools/reliable_quic_stream_peer.h"
#include "net/spdy/spdy_framer.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::hash_map;
using std::set;
using std::vector;
using testing::_;
using testing::InSequence;
using testing::InvokeWithoutArgs;
using testing::StrictMock;

namespace net {
namespace test {
namespace {

const QuicPriority kSomeMiddlePriority = 2;

class TestCryptoStream : public QuicCryptoStream {
 public:
  explicit TestCryptoStream(QuicSession* session)
      : QuicCryptoStream(session) {
  }

  virtual void OnHandshakeMessage(
      const CryptoHandshakeMessage& message) OVERRIDE {
    encryption_established_ = true;
    handshake_confirmed_ = true;
    CryptoHandshakeMessage msg;
    string error_details;
    session()->config()->ToHandshakeMessage(&msg);
    const QuicErrorCode error = session()->config()->ProcessClientHello(
        msg, &error_details);
    EXPECT_EQ(QUIC_NO_ERROR, error);
    session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
  }

  MOCK_METHOD0(OnCanWrite, void());
};

class TestStream : public ReliableQuicStream {
 public:
  TestStream(QuicStreamId id, QuicSession* session)
      : ReliableQuicStream(id, session) {
  }

  using ReliableQuicStream::CloseWriteSide;

  virtual uint32 ProcessData(const char* data, uint32 data_len) {
    return data_len;
  }

  MOCK_METHOD0(OnCanWrite, void());
};

// Poor man's functor for use as callback in a mock.
class StreamBlocker {
 public:
  StreamBlocker(QuicSession* session, QuicStreamId stream_id)
      : session_(session),
        stream_id_(stream_id) {
  }

  void MarkWriteBlocked() {
    session_->MarkWriteBlocked(stream_id_, kSomeMiddlePriority);
  }

 private:
  QuicSession* const session_;
  const QuicStreamId stream_id_;
};

class TestSession : public QuicSession {
 public:
  TestSession(QuicConnection* connection, bool is_server)
      : QuicSession(connection, DefaultQuicConfig(), is_server),
        crypto_stream_(this) {
  }

  virtual TestCryptoStream* GetCryptoStream() OVERRIDE {
    return &crypto_stream_;
  }

  virtual TestStream* CreateOutgoingReliableStream() OVERRIDE {
    TestStream* stream = new TestStream(GetNextStreamId(), this);
    ActivateStream(stream);
    return stream;
  }

  virtual TestStream* CreateIncomingReliableStream(QuicStreamId id) OVERRIDE {
    return new TestStream(id, this);
  }

  bool IsClosedStream(QuicStreamId id) {
    return QuicSession::IsClosedStream(id);
  }

  ReliableQuicStream* GetIncomingReliableStream(QuicStreamId stream_id) {
    return QuicSession::GetIncomingReliableStream(stream_id);
  }

  TestCryptoStream crypto_stream_;
};

class QuicSessionTest : public ::testing::Test {
 protected:
  QuicSessionTest()
      : guid_(1),
        connection_(new MockConnection(guid_, IPEndPoint(), false)),
        session_(connection_, true) {
    headers_[":host"] = "www.google.com";
    headers_[":path"] = "/index.hml";
    headers_[":scheme"] = "http";
    headers_["cookie"] =
        "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
        "__utmc=160408618; "
        "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
        "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
        "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
        "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
        "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
        "1zFMi5vzcns38-8_Sns; "
        "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
        "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
        "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
        "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
        "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
        "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
        "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
        "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
        "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
        "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
        "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
        "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
        "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
        "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
        "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
  }

  void CheckClosedStreams() {
    for (int i = kCryptoStreamId; i < 100; i++) {
      if (closed_streams_.count(i) == 0) {
        EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i;
      } else {
        EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i;
      }
    }
  }

  void CloseStream(QuicStreamId id) {
    session_.CloseStream(id);
    closed_streams_.insert(id);
  }

  QuicGuid guid_;
  MockConnection* connection_;
  TestSession session_;
  set<QuicStreamId> closed_streams_;
  SpdyHeaderBlock headers_;
};

TEST_F(QuicSessionTest, PeerAddress) {
  EXPECT_EQ(IPEndPoint(), session_.peer_address());
}

TEST_F(QuicSessionTest, IsCryptoHandshakeConfirmed) {
  EXPECT_FALSE(session_.IsCryptoHandshakeConfirmed());
  CryptoHandshakeMessage message;
  session_.crypto_stream_.OnHandshakeMessage(message);
  EXPECT_TRUE(session_.IsCryptoHandshakeConfirmed());
}

TEST_F(QuicSessionTest, IsClosedStreamDefault) {
  // Ensure that no streams are initially closed.
  for (int i = kCryptoStreamId; i < 100; i++) {
    EXPECT_FALSE(session_.IsClosedStream(i));
  }
}

TEST_F(QuicSessionTest, ImplicitlyCreatedStreams) {
  ASSERT_TRUE(session_.GetIncomingReliableStream(7) != NULL);
  // Both 3 and 5 should be implicitly created.
  EXPECT_FALSE(session_.IsClosedStream(3));
  EXPECT_FALSE(session_.IsClosedStream(5));
  ASSERT_TRUE(session_.GetIncomingReliableStream(5) != NULL);
  ASSERT_TRUE(session_.GetIncomingReliableStream(3) != NULL);
}

TEST_F(QuicSessionTest, IsClosedStreamLocallyCreated) {
  TestStream* stream2 = session_.CreateOutgoingReliableStream();
  EXPECT_EQ(2u, stream2->id());
  ReliableQuicStreamPeer::SetHeadersDecompressed(stream2, true);
  TestStream* stream4 = session_.CreateOutgoingReliableStream();
  EXPECT_EQ(4u, stream4->id());
  ReliableQuicStreamPeer::SetHeadersDecompressed(stream4, true);

  CheckClosedStreams();
  CloseStream(4);
  CheckClosedStreams();
  CloseStream(2);
  CheckClosedStreams();
}

TEST_F(QuicSessionTest, IsClosedStreamPeerCreated) {
  ReliableQuicStream* stream3 = session_.GetIncomingReliableStream(3);
  ReliableQuicStreamPeer::SetHeadersDecompressed(stream3, true);
  ReliableQuicStream* stream5 = session_.GetIncomingReliableStream(5);
  ReliableQuicStreamPeer::SetHeadersDecompressed(stream5, true);

  CheckClosedStreams();
  CloseStream(3);
  CheckClosedStreams();
  CloseStream(5);
  // Create stream id 9, and implicitly 7
  ReliableQuicStream* stream9 = session_.GetIncomingReliableStream(9);
  ReliableQuicStreamPeer::SetHeadersDecompressed(stream9, true);
  CheckClosedStreams();
  // Close 9, but make sure 7 is still not closed
  CloseStream(9);
  CheckClosedStreams();
}

TEST_F(QuicSessionTest, StreamIdTooLarge) {
  session_.GetIncomingReliableStream(3);
  EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID));
  session_.GetIncomingReliableStream(105);
}

TEST_F(QuicSessionTest, DecompressionError) {
  ReliableQuicStream* stream = session_.GetIncomingReliableStream(3);
  EXPECT_CALL(*connection_, SendConnectionClose(QUIC_DECOMPRESSION_FAILURE));
  const char data[] =
      "\1\0\0\0"   // headers id
      "\0\0\0\4"   // length
      "abcd";      // invalid compressed data
  stream->ProcessRawData(data, arraysize(data));
}

TEST_F(QuicSessionTest, OnCanWrite) {
  TestStream* stream2 = session_.CreateOutgoingReliableStream();
  TestStream* stream4 = session_.CreateOutgoingReliableStream();
  TestStream* stream6 = session_.CreateOutgoingReliableStream();

  session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority);
  session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority);
  session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority);

  InSequence s;
  StreamBlocker stream2_blocker(&session_, stream2->id());
  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(
      // Reregister, to test the loop limit.
      InvokeWithoutArgs(&stream2_blocker, &StreamBlocker::MarkWriteBlocked));
  EXPECT_CALL(*stream6, OnCanWrite());
  EXPECT_CALL(*stream4, OnCanWrite());

  EXPECT_FALSE(session_.OnCanWrite());
}

TEST_F(QuicSessionTest, BufferedHandshake) {
  EXPECT_FALSE(session_.HasPendingHandshake());  // Default value.

  // Test that blocking other streams does not change our status.
  TestStream* stream2 = session_.CreateOutgoingReliableStream();
  StreamBlocker stream2_blocker(&session_, stream2->id());
  stream2_blocker.MarkWriteBlocked();
  EXPECT_FALSE(session_.HasPendingHandshake());

  TestStream* stream3 = session_.CreateOutgoingReliableStream();
  StreamBlocker stream3_blocker(&session_, stream3->id());
  stream3_blocker.MarkWriteBlocked();
  EXPECT_FALSE(session_.HasPendingHandshake());

  // Blocking (due to buffering of) the Crypto stream is detected.
  session_.MarkWriteBlocked(kCryptoStreamId, kSomeMiddlePriority);
  EXPECT_TRUE(session_.HasPendingHandshake());

  TestStream* stream4 = session_.CreateOutgoingReliableStream();
  StreamBlocker stream4_blocker(&session_, stream4->id());
  stream4_blocker.MarkWriteBlocked();
  EXPECT_TRUE(session_.HasPendingHandshake());

  InSequence s;
  // Force most streams to re-register, which is common scenario when we block
  // the Crypto stream, and only the crypto stream can "really" write.

  // Due to prioritization, we *should* be asked to write the crypto stream
  // first.
  // Don't re-register the crypto stream (which signals complete writing).
  TestCryptoStream* crypto_stream = session_.GetCryptoStream();
  EXPECT_CALL(*crypto_stream, OnCanWrite());

  // Re-register all other streams, to show they weren't able to proceed.
  EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(
      InvokeWithoutArgs(&stream2_blocker, &StreamBlocker::MarkWriteBlocked));

  EXPECT_CALL(*stream3, OnCanWrite()).WillOnce(
      InvokeWithoutArgs(&stream3_blocker, &StreamBlocker::MarkWriteBlocked));

  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(
      InvokeWithoutArgs(&stream4_blocker, &StreamBlocker::MarkWriteBlocked));

  EXPECT_FALSE(session_.OnCanWrite());
  EXPECT_FALSE(session_.HasPendingHandshake());  // Crypto stream wrote.
}

TEST_F(QuicSessionTest, OnCanWriteWithClosedStream) {
  TestStream* stream2 = session_.CreateOutgoingReliableStream();
  TestStream* stream4 = session_.CreateOutgoingReliableStream();
  TestStream* stream6 = session_.CreateOutgoingReliableStream();

  session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority);
  session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority);
  session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority);
  CloseStream(stream6->id());

  InSequence s;
  EXPECT_CALL(*stream2, OnCanWrite());
  EXPECT_CALL(*stream4, OnCanWrite());
  EXPECT_TRUE(session_.OnCanWrite());
}

// Regression test for http://crbug.com/248737
TEST_F(QuicSessionTest, OutOfOrderHeaders) {
  QuicSpdyCompressor compressor;
  vector<QuicStreamFrame> frames;
  QuicPacketHeader header;
  header.public_header.guid = session_.guid();

  TestStream* stream2 = session_.CreateOutgoingReliableStream();
  TestStream* stream4 = session_.CreateOutgoingReliableStream();
  stream2->CloseWriteSide();
  stream4->CloseWriteSide();

  // Create frame with headers for stream2.
  string compressed_headers1 = compressor.CompressHeaders(headers_);
  QuicStreamFrame frame1(stream2->id(), false, 0, compressed_headers1);

  // Create frame with headers for stream4.
  string compressed_headers2 = compressor.CompressHeaders(headers_);
  QuicStreamFrame frame2(stream4->id(), true, 0, compressed_headers2);

  // Process the second frame first.  This will cause the headers to
  // be queued up and processed after the first frame is processed.
  frames.push_back(frame2);
  session_.OnStreamFrames(frames);

  // Process the first frame, and un-cork the buffered headers.
  frames[0] = frame1;
  session_.OnStreamFrames(frames);

  // Ensure that the streams actually close and we don't DCHECK.
  connection_->CloseConnection(QUIC_CONNECTION_TIMED_OUT, true);
}

TEST_F(QuicSessionTest, SendGoAway) {
  // After sending a GoAway, ensure new incoming streams cannot be created and
  // result in a RST being sent.
  EXPECT_CALL(*connection_,
              SendGoAway(QUIC_PEER_GOING_AWAY, 0u, "Going Away."));
  session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
  EXPECT_TRUE(session_.goaway_sent());

  EXPECT_CALL(*connection_, SendRstStream(3u, QUIC_STREAM_PEER_GOING_AWAY));
  EXPECT_FALSE(session_.GetIncomingReliableStream(3u));
}

TEST_F(QuicSessionTest, IncreasedTimeoutAfterCryptoHandshake) {
  EXPECT_EQ(kDefaultInitialTimeoutSecs,
            QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
  CryptoHandshakeMessage msg;
  session_.crypto_stream_.OnHandshakeMessage(msg);
  EXPECT_EQ(kDefaultTimeoutSecs,
            QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
}

TEST_F(QuicSessionTest, ZombieStream) {
  StrictMock<MockConnection>* connection =
      new StrictMock<MockConnection>(guid_, IPEndPoint(), false);
  TestSession session(connection, /*is_server=*/ false);

  TestStream* stream3 = session.CreateOutgoingReliableStream();
  EXPECT_EQ(3u, stream3->id());
  TestStream* stream5 = session.CreateOutgoingReliableStream();
  EXPECT_EQ(5u, stream5->id());
  EXPECT_EQ(2u, session.GetNumOpenStreams());

  // Reset the stream, but since the headers have not been decompressed
  // it will become a zombie and will continue to process data
  // until the headers are decompressed.
  EXPECT_CALL(*connection, SendRstStream(3, QUIC_STREAM_CANCELLED));
  session.SendRstStream(3, QUIC_STREAM_CANCELLED);

  EXPECT_EQ(1u, session.GetNumOpenStreams());

  vector<QuicStreamFrame> frames;
  QuicPacketHeader header;
  header.public_header.guid = session_.guid();

  // Create frame with headers for stream2.
  QuicSpdyCompressor compressor;
  string compressed_headers1 = compressor.CompressHeaders(headers_);
  QuicStreamFrame frame1(stream3->id(), false, 0, compressed_headers1);

  // Process the second frame first.  This will cause the headers to
  // be queued up and processed after the first frame is processed.
  frames.push_back(frame1);
  EXPECT_FALSE(stream3->headers_decompressed());

  session.OnStreamFrames(frames);
  EXPECT_EQ(1u, session.GetNumOpenStreams());

  EXPECT_TRUE(connection->connected());
}

TEST_F(QuicSessionTest, ZombieStreamConnectionClose) {
  StrictMock<MockConnection>* connection =
      new StrictMock<MockConnection>(guid_, IPEndPoint(), false);
  TestSession session(connection, /*is_server=*/ false);

  TestStream* stream3 = session.CreateOutgoingReliableStream();
  EXPECT_EQ(3u, stream3->id());
  TestStream* stream5 = session.CreateOutgoingReliableStream();
  EXPECT_EQ(5u, stream5->id());
  EXPECT_EQ(2u, session.GetNumOpenStreams());

  stream3->CloseWriteSide();
  // Reset the stream, but since the headers have not been decompressed
  // it will become a zombie and will continue to process data
  // until the headers are decompressed.
  EXPECT_CALL(*connection, SendRstStream(3, QUIC_STREAM_CANCELLED));
  session.SendRstStream(3, QUIC_STREAM_CANCELLED);

  EXPECT_EQ(1u, session.GetNumOpenStreams());

  connection->CloseConnection(QUIC_CONNECTION_TIMED_OUT, false);

  EXPECT_EQ(0u, session.GetNumOpenStreams());
}

}  // namespace
}  // namespace test
}  // namespace net
