#include <benchmark/benchmark.h>

#include "CXXGraph/CXXGraph.hpp"
#include "Utilities.hpp"

// static CXXGraph::Graph<int> *graph;

static void GraphCreation(benchmark::State &state) {
  for (auto _ : state) {
    CXXGraph::Graph<int> g;
  }
}

BENCHMARK(GraphCreation)->Complexity();

static void AddEdge(benchmark::State &state) {
  CXXGraph::Graph<int> g;
  auto n1 = *nodes.at(0);
  auto n2 = *nodes.at(1);
  CXXGraph::Edge<int> e(1, n1, n2);
  for (auto _ : state) {
    g.addEdge(&e);
  }
}
BENCHMARK(AddEdge)->Complexity();

static void AddEdgeX(benchmark::State &state) {
  CXXGraph::Graph<int> g;
  auto range_start = edges.begin();
  auto range_end = edges.find(state.range(0));
  std::unordered_map<unsigned long, CXXGraph::Edge<int> *> edgesX;
  edgesX.insert(range_start, range_end);
  for (auto _ : state) {
    for (auto e : edgesX) {
      g.addEdge(&(*e.second));
    }
  }
}
BENCHMARK(AddEdgeX)
    ->RangeMultiplier(16)
    ->Range((unsigned long)1, (unsigned long)1 << 16)
    ->Complexity();

static void ReadGraphCitHep(benchmark::State &state) {
  for (auto _ : state) {
    auto g = readGraph("CitHepPh");
    delete g;
  }
}

BENCHMARK(ReadGraphCitHep)->Complexity();

static void getEdgeSetX(benchmark::State &state) {
  CXXGraph::Graph<int> g;
  auto range_start = edges.begin();
  auto range_end = edges.find(state.range(0));
  std::unordered_map<unsigned long, CXXGraph::Edge<int> *> edgesX;
  edgesX.insert(range_start, range_end);
  for (auto e : edgesX) {
    g.addEdge(&(*e.second));
  }
  for (auto _ : state) {
    auto edgeSet = g.getEdgeSet();
  }
}

BENCHMARK(getEdgeSetX)
    ->RangeMultiplier(16)
    ->Range((unsigned long)1, (unsigned long)1 << 16)
    ->Complexity();

static void getNodeSetX(benchmark::State &state) {
  CXXGraph::Graph<int> g;
  auto range_start = edges.begin();
  auto range_end = edges.find(state.range(0));
  std::unordered_map<unsigned long, CXXGraph::Edge<int> *> edgesX;
  edgesX.insert(range_start, range_end);
  for (auto e : edgesX) {
    g.addEdge(&(*e.second));
  }
  for (auto _ : state) {
    auto nodeSet = g.getNodeSet();
  }
}

BENCHMARK(getNodeSetX)
    ->RangeMultiplier(16)
    ->Range((unsigned long)1, (unsigned long)1 << 16)
    ->Complexity();

static void getEdgeSetCitHep(benchmark::State &state) {
  for (auto _ : state) {
    auto edgeSet = cit_graph_ptr->getEdgeSet();
  }
}

BENCHMARK(getEdgeSetCitHep)->Complexity();

static void getNodeSetCitHep(benchmark::State &state) {
  for (auto _ : state) {
    auto nodeSet = cit_graph_ptr->getNodeSet();
  }
}

BENCHMARK(getNodeSetCitHep)->Complexity();

static void getAdjMatrixX(benchmark::State &state) {
  CXXGraph::Graph<int> g;
  auto range_start = undirectedEdges.begin();
  auto range_end = undirectedEdges.find(state.range(0));
  std::unordered_map<unsigned long, CXXGraph::UndirectedEdge<int> *> edgesX;
  edgesX.insert(range_start, range_end);
  for (auto e : edgesX) {
    g.addEdge(&(*e.second));
  }
  for (auto _ : state) {
    auto adjMatrix = g.getAdjMatrix();
  }
}

BENCHMARK(getAdjMatrixX)
    ->RangeMultiplier(16)
    ->Range((unsigned long)1, (unsigned long)1 << 16)
    ->Complexity();

static void getAdjMatrixCitHep(benchmark::State &state) {
  for (auto _ : state) {
    auto adjMatrix = cit_graph_ptr->getAdjMatrix();
  }
}

BENCHMARK(getAdjMatrixCitHep)->Complexity();
