// 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 <algorithm>
#include <vector>

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "net/quic/quic_fec_group.h"
#include "testing/gmock/include/gmock/gmock.h"

using ::testing::_;
using base::StringPiece;

namespace net {

namespace {

const char* kData[] = {
    "abc12345678",
    "987defg",
    "ghi12345",
    "987jlkmno",
    "mno4567890",
    "789pqrstuvw",
};

}  // namespace

class QuicFecGroupTest : public ::testing::Test {
 protected:
  void RunTest(size_t num_packets, size_t lost_packet, bool out_of_order) {
    size_t max_len = strlen(kData[0]);
    scoped_array<char>redundancy(new char[max_len]);
    for (size_t i = 0; i < max_len; i++) {
      // Initialize to the first packet.
      redundancy[i] = kData[0][i];
      // XOR in the remaining packets.
      for (size_t packet = 1; packet < num_packets; packet++) {
        uint8 byte = i > strlen(kData[packet]) ? 0x00 : kData[packet][i];
        redundancy[i] = redundancy[i] ^ byte;
      }
    }

    QuicFecGroup group;

    // If we're out of order, send the FEC packet in the position of the
    // lost packet. Otherwise send all (non-missing) packets, then FEC.
    if (out_of_order) {
      // Update the FEC state for each non-lost packet.
      for (size_t packet = 0; packet < num_packets; packet++) {
        if (packet == lost_packet) {
          ASSERT_FALSE(group.IsFinished());
          QuicFecData fec;
          fec.min_protected_packet_sequence_number = 0;
          fec.redundancy = StringPiece(redundancy.get(), strlen(kData[0]));
          ASSERT_TRUE(group.UpdateFec(num_packets, fec));
        } else {
          QuicPacketHeader header;
          header.packet_sequence_number = packet;
          ASSERT_TRUE(group.Update(header, kData[packet]));
        }
        ASSERT_TRUE(group.CanRevive() == (packet == num_packets - 1));
      }
    } else {
    // Update the FEC state for each non-lost packet.
      for (size_t packet = 0; packet < num_packets; packet++) {
        if (packet == lost_packet) {
          continue;
        }

        QuicPacketHeader header;
        header.packet_sequence_number = packet;
        ASSERT_TRUE(group.Update(header, kData[packet]));
        ASSERT_FALSE(group.CanRevive());
      }

      ASSERT_FALSE(group.IsFinished());
      // Attempt to revive the missing packet.
      QuicFecData fec;
      fec.min_protected_packet_sequence_number = 0;
      fec.redundancy = StringPiece(redundancy.get(), strlen(kData[0]));

      ASSERT_TRUE(group.UpdateFec(num_packets, fec));
    }
    QuicPacketHeader header;
    char recovered[kMaxPacketSize];
    ASSERT_TRUE(group.CanRevive());
    size_t len = group.Revive(&header, recovered, arraysize(recovered));
    ASSERT_NE(0u, len)
        << "Failed to revive packet " << lost_packet << " out of "
        << num_packets;
    EXPECT_EQ(lost_packet, header.packet_sequence_number)
        << "Failed to revive packet " << lost_packet << " out of "
        << num_packets;
    ASSERT_GE(len, strlen(kData[lost_packet])) << "Incorrect length";
    for (size_t i = 0; i < strlen(kData[lost_packet]); i++) {
      EXPECT_EQ(kData[lost_packet][i], recovered[i]);
    }
    ASSERT_TRUE(group.IsFinished());
  }
};

TEST_F(QuicFecGroupTest, UpdateAndRevive) {
  RunTest(2, 0, false);
  RunTest(2, 1, false);

  RunTest(3, 0, false);
  RunTest(3, 1, false);
  RunTest(3, 2, false);
}

TEST_F(QuicFecGroupTest, UpdateAndReviveOutOfOrder) {
  RunTest(2, 0, true);
  RunTest(2, 1, true);

  RunTest(3, 0, true);
  RunTest(3, 1, true);
  RunTest(3, 2, true);
}

TEST_F(QuicFecGroupTest, UpdateFecIfReceivedPacketIsNotCovered) {
  char data1[] = "abc123";
  char redundancy[arraysize(data1)];
  for (size_t i = 0; i < arraysize(data1); i++) {
    redundancy[i] = data1[i];
  }

  QuicFecGroup group;

  QuicPacketHeader header;
  header.packet_sequence_number = 3;
  group.Update(header, data1);

  QuicFecData fec;
  fec.min_protected_packet_sequence_number = 1;
  fec.redundancy = redundancy;

  ASSERT_FALSE(group.UpdateFec(2, fec));
}

TEST_F(QuicFecGroupTest, ProtectsPacketsBefore) {
  QuicPacketHeader header;
  header.packet_sequence_number = 3;

  QuicFecGroup group;
  ASSERT_TRUE(group.Update(header, kData[0]));

  EXPECT_FALSE(group.ProtectsPacketsBefore(1));
  EXPECT_FALSE(group.ProtectsPacketsBefore(2));
  EXPECT_FALSE(group.ProtectsPacketsBefore(3));
  EXPECT_TRUE(group.ProtectsPacketsBefore(4));
  EXPECT_TRUE(group.ProtectsPacketsBefore(5));
  EXPECT_TRUE(group.ProtectsPacketsBefore(50));
}

TEST_F(QuicFecGroupTest, ProtectsPacketsBeforeWithSeveralPackets) {
  QuicPacketHeader header;
  header.packet_sequence_number = 3;

  QuicFecGroup group;
  ASSERT_TRUE(group.Update(header, kData[0]));

  header.packet_sequence_number = 7;
  ASSERT_TRUE(group.Update(header, kData[0]));

  header.packet_sequence_number = 5;
  ASSERT_TRUE(group.Update(header, kData[0]));

  EXPECT_FALSE(group.ProtectsPacketsBefore(1));
  EXPECT_FALSE(group.ProtectsPacketsBefore(2));
  EXPECT_FALSE(group.ProtectsPacketsBefore(3));
  EXPECT_TRUE(group.ProtectsPacketsBefore(4));
  EXPECT_TRUE(group.ProtectsPacketsBefore(5));
  EXPECT_TRUE(group.ProtectsPacketsBefore(6));
  EXPECT_TRUE(group.ProtectsPacketsBefore(7));
  EXPECT_TRUE(group.ProtectsPacketsBefore(8));
  EXPECT_TRUE(group.ProtectsPacketsBefore(9));
  EXPECT_TRUE(group.ProtectsPacketsBefore(50));
}

TEST_F(QuicFecGroupTest, ProtectsPacketsBeforeWithFecData) {
  QuicFecData fec;
  fec.min_protected_packet_sequence_number = 2;
  fec.redundancy = kData[0];

  QuicFecGroup group;
  ASSERT_TRUE(group.UpdateFec(3, fec));

  EXPECT_FALSE(group.ProtectsPacketsBefore(1));
  EXPECT_FALSE(group.ProtectsPacketsBefore(2));
  EXPECT_TRUE(group.ProtectsPacketsBefore(3));
  EXPECT_TRUE(group.ProtectsPacketsBefore(4));
  EXPECT_TRUE(group.ProtectsPacketsBefore(5));
  EXPECT_TRUE(group.ProtectsPacketsBefore(50));
}

}  // namespace net
