//===- llvm/unittest/XRay/GraphTest.cpp - XRay Graph unit tests -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/XRay/Graph.h"
#include "gtest/gtest.h"
#include <iostream>
#include <set>
#include <type_traits>

using namespace llvm;
using namespace xray;

namespace {
struct VAttr {
  unsigned VA;
};
struct EAttr {
  unsigned EA;
};
typedef Graph<VAttr, EAttr, unsigned> GraphT;
typedef typename GraphT::VertexIdentifier VI;
typedef typename GraphT::EdgeIdentifier EI;

// Test Fixture
template <typename T> class GraphTest : public testing::Test {
protected:
  T Graph = getTestGraph();

private:
  static T getTestGraph() {
    using std::make_pair;
    std::remove_const_t<T> G;
    G.insert(make_pair(1u, VAttr({3u})));
    G.insert(make_pair(2u, VAttr({5u})));
    G.insert(make_pair(3u, VAttr({7u})));
    G.insert(make_pair(4u, VAttr({11u})));
    G.insert(make_pair(5u, VAttr({13u})));
    G.insert(make_pair(6u, VAttr({17u})));

    G.insert(std::make_pair(EI(1u, 2u), EAttr({3u * 5u})));
    G.insert(std::make_pair(EI(2u, 3u), EAttr({5u * 7u})));
    G.insert(std::make_pair(EI(6u, 3u), EAttr({2u * 7u * 17u})));
    G.insert(std::make_pair(EI(4u, 6u), EAttr({11u * 17u})));
    G.insert(std::make_pair(EI(2u, 4u), EAttr({5u * 11u})));
    G.insert(std::make_pair(EI(2u, 5u), EAttr({5u * 13u})));
    G.insert(std::make_pair(EI(4u, 5u), EAttr({11u * 13u})));

    return G;
  }
};

typedef ::testing::Types<GraphT, const GraphT> GraphTestTypes;

using VVT = typename GraphT::VertexValueType;
using EVT = typename GraphT::EdgeValueType;

TYPED_TEST_SUITE(GraphTest, GraphTestTypes, );

template <typename T> void graphVertexTester(T &G) {
  std::set<unsigned> V({1u, 2u, 3u, 4u, 5u, 6u});
  std::vector<unsigned> VA({0u, 3u, 5u, 7u, 11u, 13u, 17u});

  EXPECT_EQ(V.size(), G.vertices().size());
  EXPECT_FALSE(G.vertices().empty());
  for (unsigned u : V) {
    auto EVV = G.at(u);
    ASSERT_TRUE(!!EVV);
    EXPECT_EQ(1u, G.count(u));
    EXPECT_EQ(VA[u], EVV->VA);
    EXPECT_TRUE(llvm::is_contained(llvm::make_first_range(G.vertices()), u));
    consumeError(EVV.takeError());
  }

  for (auto &VVT : G.vertices()) {
    EXPECT_EQ(1u, V.count(VVT.first));
    EXPECT_EQ(VA[VVT.first], VVT.second.VA);
  }
}

template <typename T> void graphEdgeTester(T &G) {
  std::set<std::pair<unsigned, unsigned>> E(
      {{1u, 2u}, {2u, 3u}, {6u, 3u}, {4u, 6u}, {2u, 4u}, {2u, 5u}, {4u, 5u}});
  std::vector<unsigned> VA({0u, 3u, 5u, 7u, 11u, 13u, 17u});

  EXPECT_EQ(E.size(), G.edges().size());
  EXPECT_FALSE(G.edges().empty());
  for (std::pair<unsigned, unsigned> u : E) {
    auto EEV = G.at(u);
    ASSERT_TRUE(!!EEV);
    EXPECT_EQ(1u, G.count(u));
    EXPECT_EQ(VA[u.first] * VA[u.second] * ((u.first > u.second) ? 2 : 1),
              EEV->EA);
    EXPECT_TRUE(llvm::is_contained(llvm::make_first_range(G.edges()), u));
    consumeError(EEV.takeError());
  }

  for (auto &EV : G.edges()) {
    EXPECT_EQ(1u, E.count(EV.first));
    EXPECT_EQ(VA[EV.first.first] * VA[EV.first.second] *
                  ((EV.first.first > EV.first.second) ? 2 : 1),
              EV.second.EA);
    const auto &IE = G.inEdges(EV.first.second);
    const auto &OE = G.outEdges(EV.first.first);
    EXPECT_NE(IE.size(), 0u);
    EXPECT_NE(OE.size(), 0u);
    EXPECT_NE(IE.begin(), IE.end());
    EXPECT_NE(OE.begin(), OE.end());
    EXPECT_TRUE(llvm::is_contained(
        llvm::make_first_range(G.inEdges(EV.first.second)), EV.first));
    EXPECT_FALSE(llvm::is_contained(
        llvm::make_first_range(G.inEdges(EV.first.first)), EV.first));
    EXPECT_FALSE(llvm::is_contained(
        llvm::make_first_range(G.outEdges(EV.first.second)), EV.first));
    EXPECT_TRUE(llvm::is_contained(
        llvm::make_first_range(G.outEdges(EV.first.first)), EV.first));
  }
}

TYPED_TEST(GraphTest, TestGraphEdge) {
  auto &G = this->Graph;

  graphEdgeTester(G);
}

TYPED_TEST(GraphTest, TestGraphVertex) {
  auto &G = this->Graph;

  graphVertexTester(G);
}

TYPED_TEST(GraphTest, TestCopyConstructor) {
  TypeParam G(this->Graph);

  graphEdgeTester(G);
  graphVertexTester(G);
}

TYPED_TEST(GraphTest, TestCopyAssign) {
  TypeParam G = this->Graph;

  graphEdgeTester(G);
  graphVertexTester(G);
}

TYPED_TEST(GraphTest, TestMoveConstructor) {
  TypeParam G(std::move(this->Graph));

  graphEdgeTester(G);
  graphVertexTester(G);
}

// Tests the incremental Construction of a graph
TEST(GraphTest, TestConstruction) {
  GraphT MG;
  const GraphT &G = MG;
  EXPECT_EQ(0u, G.count(0u));
  EXPECT_EQ(0u, G.count({0u, 1u}));
  auto VE = G.at(0);
  auto EE = G.at({0, 0});
  EXPECT_FALSE(VE); // G.at[0] returns an error
  EXPECT_FALSE(EE); // G.at[{0,0}] returns an error
  consumeError(VE.takeError());
  consumeError(EE.takeError());
  EXPECT_TRUE(G.vertices().empty());
  EXPECT_TRUE(G.edges().empty());
  EXPECT_EQ(G.vertices().begin(), G.vertices().end());
  EXPECT_EQ(G.edges().begin(), G.edges().end());
}

TEST(GraphTest, TestiVertexAccessOperator) {
  GraphT MG;
  const GraphT &G = MG;

  MG[0u] = {1u};
  EXPECT_EQ(1u, MG[0u].VA);
  EXPECT_EQ(1u, G.count(0u));
  EXPECT_EQ(0u, G.count(1u));
  EXPECT_EQ(1u, MG[0u].VA);
  auto T = G.at(0u);
  EXPECT_TRUE(!!T);
  EXPECT_EQ(1u, T->VA);

  EXPECT_EQ(1u, G.vertices().size());
  EXPECT_EQ(0u, G.edges().size());
  EXPECT_FALSE(G.vertices().empty());
  EXPECT_TRUE(G.edges().empty());
  EXPECT_NE(G.vertices().begin(), G.vertices().end());
  EXPECT_EQ(G.edges().begin(), G.edges().end());
  EXPECT_EQ(1u, G.vertices().begin()->second.VA);
  EXPECT_EQ(0u, G.vertices().begin()->first);
  EXPECT_EQ(0u, G.outEdges(0u).size());
  EXPECT_TRUE(G.outEdges(0u).empty());
  EXPECT_EQ(G.outEdges(0u).begin(), G.outEdges(0u).end());
  EXPECT_EQ(0u, G.inEdges(0u).size());
  EXPECT_TRUE(G.inEdges(0u).empty());
  EXPECT_EQ(G.inEdges(0u).begin(), G.inEdges(0u).end());
}

TEST(GraphTest, TestEdgeAccessOperator) {
  GraphT MG;
  const GraphT &G = MG;

  MG[{0u, 0u}] = {2u};
  EI EdgeIdent({0u, 0u});
  EXPECT_EQ(2u, MG[EdgeIdent].EA);
  EXPECT_EQ(1u, G.count({0u, 0u}));
  EXPECT_EQ(0u, G.count({0u, 1u}));
  EXPECT_EQ(1u, G.count(0u));
  EXPECT_NE(1u, G.count(1u));
  auto T = G.at({0u, 0u});
  EXPECT_TRUE(T && T->EA == 2u);
  EXPECT_EQ(1u, G.edges().size());
  EXPECT_EQ(1u, G.vertices().size());
  EXPECT_FALSE(G.edges().empty());
  EXPECT_FALSE(G.vertices().empty());
  EXPECT_NE(G.edges().begin(), G.edges().end());
  EXPECT_EQ(EI(0u, 0u), G.edges().begin()->first);
  EXPECT_EQ(2u, G.edges().begin()->second.EA);
  EXPECT_EQ(1u, G.outEdges(0u).size());
  EXPECT_FALSE(G.outEdges(0u).empty());
  EXPECT_NE(G.outEdges(0u).begin(), G.outEdges(0u).end());
  EXPECT_EQ(EI(0u, 0u), G.outEdges(0u).begin()->first);
  EXPECT_EQ(2u, G.outEdges(0u).begin()->second.EA);
  EXPECT_EQ(++(G.outEdges(0u).begin()), G.outEdges(0u).end());
  EXPECT_EQ(1u, G.inEdges(0u).size());
  EXPECT_FALSE(G.inEdges(0u).empty());
  EXPECT_NE(G.inEdges(0u).begin(), G.inEdges(0u).end());
  EXPECT_EQ(EI(0u, 0u), G.inEdges(0u).begin()->first);
  EXPECT_EQ(2u, G.inEdges(0u).begin()->second.EA);
  EXPECT_EQ(++(G.inEdges(0u).begin()), G.inEdges(0u).end());
}
}
