// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "absl/synchronization/internal/graphcycles.h"

#include <map>
#include <random>
#include <unordered_set>
#include <utility>
#include <vector>

#include "gtest/gtest.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/macros.h"

namespace absl {
namespace synchronization_internal {

// We emulate a GraphCycles object with a node vector and an edge vector.
// We then compare the two implementations.

using Nodes = std::vector<int>;
struct Edge {
  int from;
  int to;
};
using Edges = std::vector<Edge>;
using RandomEngine = std::mt19937_64;

// Mapping from integer index to GraphId.
typedef std::map<int, GraphId> IdMap;
static GraphId Get(const IdMap& id, int num) {
  auto iter = id.find(num);
  return (iter == id.end()) ? InvalidGraphId() : iter->second;
}

// Return whether "to" is reachable from "from".
static bool IsReachable(Edges *edges, int from, int to,
                        std::unordered_set<int> *seen) {
  seen->insert(from);     // we are investigating "from"; don't do it again
  if (from == to) return true;
  for (const auto &edge : *edges) {
    if (edge.from == from) {
      if (edge.to == to) {  // success via edge directly
        return true;
      } else if (seen->find(edge.to) == seen->end() &&  // success via edge
                 IsReachable(edges, edge.to, to, seen)) {
        return true;
      }
    }
  }
  return false;
}

static void PrintEdges(Edges *edges) {
  ABSL_RAW_LOG(INFO, "EDGES (%zu)", edges->size());
  for (const auto &edge : *edges) {
    int a = edge.from;
    int b = edge.to;
    ABSL_RAW_LOG(INFO, "%d %d", a, b);
  }
  ABSL_RAW_LOG(INFO, "---");
}

static void PrintGCEdges(Nodes *nodes, const IdMap &id, GraphCycles *gc) {
  ABSL_RAW_LOG(INFO, "GC EDGES");
  for (int a : *nodes) {
    for (int b : *nodes) {
      if (gc->HasEdge(Get(id, a), Get(id, b))) {
        ABSL_RAW_LOG(INFO, "%d %d", a, b);
      }
    }
  }
  ABSL_RAW_LOG(INFO, "---");
}

static void PrintTransitiveClosure(Nodes *nodes, Edges *edges) {
  ABSL_RAW_LOG(INFO, "Transitive closure");
  for (int a : *nodes) {
    for (int b : *nodes) {
      std::unordered_set<int> seen;
      if (IsReachable(edges, a, b, &seen)) {
        ABSL_RAW_LOG(INFO, "%d %d", a, b);
      }
    }
  }
  ABSL_RAW_LOG(INFO, "---");
}

static void PrintGCTransitiveClosure(Nodes *nodes, const IdMap &id,
                                     GraphCycles *gc) {
  ABSL_RAW_LOG(INFO, "GC Transitive closure");
  for (int a : *nodes) {
    for (int b : *nodes) {
      if (gc->IsReachable(Get(id, a), Get(id, b))) {
        ABSL_RAW_LOG(INFO, "%d %d", a, b);
      }
    }
  }
  ABSL_RAW_LOG(INFO, "---");
}

static void CheckTransitiveClosure(Nodes *nodes, Edges *edges, const IdMap &id,
                                   GraphCycles *gc) {
  std::unordered_set<int> seen;
  for (const auto &a : *nodes) {
    for (const auto &b : *nodes) {
      seen.clear();
      bool gc_reachable = gc->IsReachable(Get(id, a), Get(id, b));
      bool reachable = IsReachable(edges, a, b, &seen);
      if (gc_reachable != reachable) {
        PrintEdges(edges);
        PrintGCEdges(nodes, id, gc);
        PrintTransitiveClosure(nodes, edges);
        PrintGCTransitiveClosure(nodes, id, gc);
        ABSL_RAW_LOG(FATAL, "gc_reachable %s reachable %s a %d b %d",
                     gc_reachable ? "true" : "false",
                     reachable ? "true" : "false", a, b);
      }
    }
  }
}

static void CheckEdges(Nodes *nodes, Edges *edges, const IdMap &id,
                       GraphCycles *gc) {
  int count = 0;
  for (const auto &edge : *edges) {
    int a = edge.from;
    int b = edge.to;
    if (!gc->HasEdge(Get(id, a), Get(id, b))) {
      PrintEdges(edges);
      PrintGCEdges(nodes, id, gc);
      ABSL_RAW_LOG(FATAL, "!gc->HasEdge(%d, %d)", a, b);
    }
  }
  for (const auto &a : *nodes) {
    for (const auto &b : *nodes) {
      if (gc->HasEdge(Get(id, a), Get(id, b))) {
        count++;
      }
    }
  }
  if (count != edges->size()) {
    PrintEdges(edges);
    PrintGCEdges(nodes, id, gc);
    ABSL_RAW_LOG(FATAL, "edges->size() %zu  count %d", edges->size(), count);
  }
}

static void CheckInvariants(const GraphCycles &gc) {
  if (ABSL_PREDICT_FALSE(!gc.CheckInvariants()))
    ABSL_RAW_LOG(FATAL, "CheckInvariants");
}

// Returns the index of a randomly chosen node in *nodes.
// Requires *nodes be non-empty.
static int RandomNode(RandomEngine* rng, Nodes *nodes) {
  std::uniform_int_distribution<int> uniform(0, nodes->size()-1);
  return uniform(*rng);
}

// Returns the index of a randomly chosen edge in *edges.
// Requires *edges be non-empty.
static int RandomEdge(RandomEngine* rng, Edges *edges) {
  std::uniform_int_distribution<int> uniform(0, edges->size()-1);
  return uniform(*rng);
}

// Returns the index of edge (from, to) in *edges or -1 if it is not in *edges.
static int EdgeIndex(Edges *edges, int from, int to) {
  int i = 0;
  while (i != edges->size() &&
         ((*edges)[i].from != from || (*edges)[i].to != to)) {
    i++;
  }
  return i == edges->size()? -1 : i;
}

TEST(GraphCycles, RandomizedTest) {
  int next_node = 0;
  Nodes nodes;
  Edges edges;   // from, to
  IdMap id;
  GraphCycles graph_cycles;
  static const int kMaxNodes = 7;  // use <= 7 nodes to keep test short
  static const int kDataOffset = 17;  // an offset to the node-specific data
  int n = 100000;
  int op = 0;
  RandomEngine rng(testing::UnitTest::GetInstance()->random_seed());
  std::uniform_int_distribution<int> uniform(0, 5);

  auto ptr = [](intptr_t i) {
    return reinterpret_cast<void*>(i + kDataOffset);
  };

  for (int iter = 0; iter != n; iter++) {
    for (const auto &node : nodes) {
      ASSERT_EQ(graph_cycles.Ptr(Get(id, node)), ptr(node)) << " node " << node;
    }
    CheckEdges(&nodes, &edges, id, &graph_cycles);
    CheckTransitiveClosure(&nodes, &edges, id, &graph_cycles);
    op = uniform(rng);
    switch (op) {
    case 0:     // Add a node
      if (nodes.size() < kMaxNodes) {
        int new_node = next_node++;
        GraphId new_gnode = graph_cycles.GetId(ptr(new_node));
        ASSERT_NE(new_gnode, InvalidGraphId());
        id[new_node] = new_gnode;
        ASSERT_EQ(ptr(new_node), graph_cycles.Ptr(new_gnode));
        nodes.push_back(new_node);
      }
      break;

    case 1:    // Remove a node
      if (nodes.size() > 0) {
        int node_index = RandomNode(&rng, &nodes);
        int node = nodes[node_index];
        nodes[node_index] = nodes.back();
        nodes.pop_back();
        graph_cycles.RemoveNode(ptr(node));
        ASSERT_EQ(graph_cycles.Ptr(Get(id, node)), nullptr);
        id.erase(node);
        int i = 0;
        while (i != edges.size()) {
          if (edges[i].from == node || edges[i].to == node) {
            edges[i] = edges.back();
            edges.pop_back();
          } else {
            i++;
          }
        }
      }
      break;

    case 2:   // Add an edge
      if (nodes.size() > 0) {
        int from = RandomNode(&rng, &nodes);
        int to = RandomNode(&rng, &nodes);
        if (EdgeIndex(&edges, nodes[from], nodes[to]) == -1) {
          if (graph_cycles.InsertEdge(id[nodes[from]], id[nodes[to]])) {
            Edge new_edge;
            new_edge.from = nodes[from];
            new_edge.to = nodes[to];
            edges.push_back(new_edge);
          } else {
            std::unordered_set<int> seen;
            ASSERT_TRUE(IsReachable(&edges, nodes[to], nodes[from], &seen))
                << "Edge " << nodes[to] << "->" << nodes[from];
          }
        }
      }
      break;

    case 3:    // Remove an edge
      if (edges.size() > 0) {
        int i = RandomEdge(&rng, &edges);
        int from = edges[i].from;
        int to = edges[i].to;
        ASSERT_EQ(i, EdgeIndex(&edges, from, to));
        edges[i] = edges.back();
        edges.pop_back();
        ASSERT_EQ(-1, EdgeIndex(&edges, from, to));
        graph_cycles.RemoveEdge(id[from], id[to]);
      }
      break;

    case 4:   // Check a path
      if (nodes.size() > 0) {
        int from = RandomNode(&rng, &nodes);
        int to = RandomNode(&rng, &nodes);
        GraphId path[2*kMaxNodes];
        int path_len = graph_cycles.FindPath(id[nodes[from]], id[nodes[to]],
                                             ABSL_ARRAYSIZE(path), path);
        std::unordered_set<int> seen;
        bool reachable = IsReachable(&edges, nodes[from], nodes[to], &seen);
        bool gc_reachable =
            graph_cycles.IsReachable(Get(id, nodes[from]), Get(id, nodes[to]));
        ASSERT_EQ(path_len != 0, reachable);
        ASSERT_EQ(path_len != 0, gc_reachable);
        // In the following line, we add one because a node can appear
        // twice, if the path is from that node to itself, perhaps via
        // every other node.
        ASSERT_LE(path_len, kMaxNodes + 1);
        if (path_len != 0) {
          ASSERT_EQ(id[nodes[from]], path[0]);
          ASSERT_EQ(id[nodes[to]], path[path_len-1]);
          for (int i = 1; i < path_len; i++) {
            ASSERT_TRUE(graph_cycles.HasEdge(path[i-1], path[i]));
          }
        }
      }
      break;

    case 5:  // Check invariants
      CheckInvariants(graph_cycles);
      break;

    default:
      ABSL_RAW_LOG(FATAL, "op %d", op);
    }

    // Very rarely, test graph expansion by adding then removing many nodes.
    std::bernoulli_distribution one_in_1024(1.0 / 1024);
    if (one_in_1024(rng)) {
      CheckEdges(&nodes, &edges, id, &graph_cycles);
      CheckTransitiveClosure(&nodes, &edges, id, &graph_cycles);
      for (int i = 0; i != 256; i++) {
        int new_node = next_node++;
        GraphId new_gnode = graph_cycles.GetId(ptr(new_node));
        ASSERT_NE(InvalidGraphId(), new_gnode);
        id[new_node] = new_gnode;
        ASSERT_EQ(ptr(new_node), graph_cycles.Ptr(new_gnode));
        for (const auto &node : nodes) {
          ASSERT_NE(node, new_node);
        }
        nodes.push_back(new_node);
      }
      for (int i = 0; i != 256; i++) {
        ASSERT_GT(nodes.size(), 0);
        int node_index = RandomNode(&rng, &nodes);
        int node = nodes[node_index];
        nodes[node_index] = nodes.back();
        nodes.pop_back();
        graph_cycles.RemoveNode(ptr(node));
        id.erase(node);
        int j = 0;
        while (j != edges.size()) {
          if (edges[j].from == node || edges[j].to == node) {
            edges[j] = edges.back();
            edges.pop_back();
          } else {
            j++;
          }
        }
      }
      CheckInvariants(graph_cycles);
    }
  }
}

class GraphCyclesTest : public ::testing::Test {
 public:
  IdMap id_;
  GraphCycles g_;

  static void* Ptr(int i) {
    return reinterpret_cast<void*>(static_cast<uintptr_t>(i));
  }

  static int Num(void* ptr) {
    return static_cast<int>(reinterpret_cast<uintptr_t>(ptr));
  }

  // Test relies on ith NewNode() call returning Node numbered i
  GraphCyclesTest() {
    for (int i = 0; i < 100; i++) {
      id_[i] = g_.GetId(Ptr(i));
    }
    CheckInvariants(g_);
  }

  bool AddEdge(int x, int y) {
    return g_.InsertEdge(Get(id_, x), Get(id_, y));
  }

  void AddMultiples() {
    // For every node x > 0: add edge to 2*x, 3*x
    for (int x = 1; x < 25; x++) {
      EXPECT_TRUE(AddEdge(x, 2*x)) << x;
      EXPECT_TRUE(AddEdge(x, 3*x)) << x;
    }
    CheckInvariants(g_);
  }

  std::string Path(int x, int y) {
    GraphId path[5];
    int np = g_.FindPath(Get(id_, x), Get(id_, y), ABSL_ARRAYSIZE(path), path);
    std::string result;
    for (int i = 0; i < np; i++) {
      if (i >= ABSL_ARRAYSIZE(path)) {
        result += " ...";
        break;
      }
      if (!result.empty()) result.push_back(' ');
      char buf[20];
      snprintf(buf, sizeof(buf), "%d", Num(g_.Ptr(path[i])));
      result += buf;
    }
    return result;
  }
};

TEST_F(GraphCyclesTest, NoCycle) {
  AddMultiples();
  CheckInvariants(g_);
}

TEST_F(GraphCyclesTest, SimpleCycle) {
  AddMultiples();
  EXPECT_FALSE(AddEdge(8, 4));
  EXPECT_EQ("4 8", Path(4, 8));
  CheckInvariants(g_);
}

TEST_F(GraphCyclesTest, IndirectCycle) {
  AddMultiples();
  EXPECT_TRUE(AddEdge(16, 9));
  CheckInvariants(g_);
  EXPECT_FALSE(AddEdge(9, 2));
  EXPECT_EQ("2 4 8 16 9", Path(2, 9));
  CheckInvariants(g_);
}

TEST_F(GraphCyclesTest, LongPath) {
  ASSERT_TRUE(AddEdge(2, 4));
  ASSERT_TRUE(AddEdge(4, 6));
  ASSERT_TRUE(AddEdge(6, 8));
  ASSERT_TRUE(AddEdge(8, 10));
  ASSERT_TRUE(AddEdge(10, 12));
  ASSERT_FALSE(AddEdge(12, 2));
  EXPECT_EQ("2 4 6 8 10 ...", Path(2, 12));
  CheckInvariants(g_);
}

TEST_F(GraphCyclesTest, RemoveNode) {
  ASSERT_TRUE(AddEdge(1, 2));
  ASSERT_TRUE(AddEdge(2, 3));
  ASSERT_TRUE(AddEdge(3, 4));
  ASSERT_TRUE(AddEdge(4, 5));
  g_.RemoveNode(g_.Ptr(id_[3]));
  id_.erase(3);
  ASSERT_TRUE(AddEdge(5, 1));
}

TEST_F(GraphCyclesTest, ManyEdges) {
  const int N = 50;
  for (int i = 0; i < N; i++) {
    for (int j = 1; j < N; j++) {
      ASSERT_TRUE(AddEdge(i, i+j));
    }
  }
  CheckInvariants(g_);
  ASSERT_TRUE(AddEdge(2*N-1, 0));
  CheckInvariants(g_);
  ASSERT_FALSE(AddEdge(10, 9));
  CheckInvariants(g_);
}

}  // namespace synchronization_internal
}  // namespace absl
