/*
 *  Copyright 2018 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "pc/rtc_stats_traversal.h"

#include <memory>
#include <vector>

#include "api/stats/rtcstats_objects.h"
#include "test/gtest.h"

// This file contains tests for TakeReferencedStats().
// GetStatsNeighborIds() is tested in rtcstats_integrationtest.cc.

namespace webrtc {

class RTCStatsTraversalTest : public ::testing::Test {
 public:
  RTCStatsTraversalTest() {
    transport_ = new RTCTransportStats("transport", 0);
    candidate_pair_ = new RTCIceCandidatePairStats("candidate-pair", 0);
    local_candidate_ = new RTCLocalIceCandidateStats("local-candidate", 0);
    remote_candidate_ = new RTCRemoteIceCandidateStats("remote-candidate", 0);
    initial_report_ = RTCStatsReport::Create(Timestamp::Zero());
    initial_report_->AddStats(std::unique_ptr<const RTCStats>(transport_));
    initial_report_->AddStats(std::unique_ptr<const RTCStats>(candidate_pair_));
    initial_report_->AddStats(
        std::unique_ptr<const RTCStats>(local_candidate_));
    initial_report_->AddStats(
        std::unique_ptr<const RTCStats>(remote_candidate_));
    result_ = RTCStatsReport::Create(Timestamp::Zero());
  }

  void TakeReferencedStats(std::vector<const RTCStats*> start_nodes) {
    std::vector<std::string> start_ids;
    start_ids.reserve(start_nodes.size());
    for (const RTCStats* start_node : start_nodes) {
      start_ids.push_back(start_node->id());
    }
    result_ = webrtc::TakeReferencedStats(initial_report_, start_ids);
  }

  void EXPECT_VISITED(const RTCStats* stats) {
    EXPECT_FALSE(initial_report_->Get(stats->id()))
        << '"' << stats->id()
        << "\" should be visited but it was not removed from initial report.";
    EXPECT_TRUE(result_->Get(stats->id()))
        << '"' << stats->id()
        << "\" should be visited but it was not added to the resulting report.";
  }

  void EXPECT_UNVISITED(const RTCStats* stats) {
    EXPECT_TRUE(initial_report_->Get(stats->id()))
        << '"' << stats->id()
        << "\" should not be visited but it was removed from initial report.";
    EXPECT_FALSE(result_->Get(stats->id()))
        << '"' << stats->id()
        << "\" should not be visited but it was added to the resulting report.";
  }

 protected:
  rtc::scoped_refptr<RTCStatsReport> initial_report_;
  rtc::scoped_refptr<RTCStatsReport> result_;
  // Raw pointers to stats owned by the reports.
  RTCTransportStats* transport_;
  RTCIceCandidatePairStats* candidate_pair_;
  RTCIceCandidateStats* local_candidate_;
  RTCIceCandidateStats* remote_candidate_;
};

TEST_F(RTCStatsTraversalTest, NoReachableConnections) {
  // Everything references transport but transport doesn't reference anything.
  //
  //          candidate-pair
  //            |    |  |
  //            v    |  v
  // local-candidate | remote-candidate
  //              |  |  |
  //              v  v  v
  //          start:transport
  candidate_pair_->transport_id = "transport";
  candidate_pair_->local_candidate_id = "local-candidate";
  candidate_pair_->remote_candidate_id = "remote-candidate";
  local_candidate_->transport_id = "transport";
  remote_candidate_->transport_id = "transport";
  TakeReferencedStats({transport_});
  EXPECT_VISITED(transport_);
  EXPECT_UNVISITED(candidate_pair_);
  EXPECT_UNVISITED(local_candidate_);
  EXPECT_UNVISITED(remote_candidate_);
}

TEST_F(RTCStatsTraversalTest, SelfReference) {
  transport_->rtcp_transport_stats_id = "transport";
  TakeReferencedStats({transport_});
  EXPECT_VISITED(transport_);
  EXPECT_UNVISITED(candidate_pair_);
  EXPECT_UNVISITED(local_candidate_);
  EXPECT_UNVISITED(remote_candidate_);
}

TEST_F(RTCStatsTraversalTest, BogusReference) {
  transport_->rtcp_transport_stats_id = "bogus-reference";
  TakeReferencedStats({transport_});
  EXPECT_VISITED(transport_);
  EXPECT_UNVISITED(candidate_pair_);
  EXPECT_UNVISITED(local_candidate_);
  EXPECT_UNVISITED(remote_candidate_);
}

TEST_F(RTCStatsTraversalTest, Tree) {
  //     start:candidate-pair
  //        |            |
  //        v            v
  // local-candidate   remote-candidate
  //       |
  //       v
  //   transport
  candidate_pair_->local_candidate_id = "local-candidate";
  candidate_pair_->remote_candidate_id = "remote-candidate";
  local_candidate_->transport_id = "transport";
  TakeReferencedStats({candidate_pair_});
  EXPECT_VISITED(transport_);
  EXPECT_VISITED(candidate_pair_);
  EXPECT_VISITED(local_candidate_);
  EXPECT_VISITED(remote_candidate_);
}

TEST_F(RTCStatsTraversalTest, MultiplePathsToSameNode) {
  //     start:candidate-pair
  //        |            |
  //        v            v
  // local-candidate   remote-candidate
  //              |     |
  //              v     v
  //             transport
  candidate_pair_->local_candidate_id = "local-candidate";
  candidate_pair_->remote_candidate_id = "remote-candidate";
  local_candidate_->transport_id = "transport";
  remote_candidate_->transport_id = "transport";
  TakeReferencedStats({candidate_pair_});
  EXPECT_VISITED(transport_);
  EXPECT_VISITED(candidate_pair_);
  EXPECT_VISITED(local_candidate_);
  EXPECT_VISITED(remote_candidate_);
}

TEST_F(RTCStatsTraversalTest, CyclicGraph) {
  //               candidate-pair
  //                  |     ^
  //                  v     |
  // start:local-candidate  |    remote-candidate
  //                    |   |
  //                    v   |
  //                  transport
  local_candidate_->transport_id = "transport";
  transport_->selected_candidate_pair_id = "candidate-pair";
  candidate_pair_->local_candidate_id = "local-candidate";
  TakeReferencedStats({local_candidate_});
  EXPECT_VISITED(transport_);
  EXPECT_VISITED(candidate_pair_);
  EXPECT_VISITED(local_candidate_);
  EXPECT_UNVISITED(remote_candidate_);
}

TEST_F(RTCStatsTraversalTest, MultipleStarts) {
  //           start:candidate-pair
  //                        |
  //                        v
  // local-candidate    remote-candidate
  //             |
  //             v
  //           start:transport
  candidate_pair_->remote_candidate_id = "remote-candidate";
  local_candidate_->transport_id = "transport";
  TakeReferencedStats({candidate_pair_, transport_});
  EXPECT_VISITED(transport_);
  EXPECT_VISITED(candidate_pair_);
  EXPECT_UNVISITED(local_candidate_);
  EXPECT_VISITED(remote_candidate_);
}

TEST_F(RTCStatsTraversalTest, MultipleStartsLeadingToSameNode) {
  //                candidate-pair
  //
  //
  // start:local-candidate   start:remote-candidate
  //                    |     |
  //                    v     v
  //                   transport
  local_candidate_->transport_id = "transport";
  remote_candidate_->transport_id = "transport";
  TakeReferencedStats({local_candidate_, remote_candidate_});
  EXPECT_VISITED(transport_);
  EXPECT_UNVISITED(candidate_pair_);
  EXPECT_VISITED(local_candidate_);
  EXPECT_VISITED(remote_candidate_);
}

}  // namespace webrtc
