/*
 *  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 <string>
#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(0);
    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(0);
  }

  void TakeReferencedStats(std::vector<const RTCStats*> start_nodes) {
    std::vector<std::string> start_ids;
    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
