/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * 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.
 */

// Based on system/update_engine/payload_generator/tarjan.cc

#ifndef LIBMEMUNREACHABLE_TARJAN_H_
#define LIBMEMUNREACHABLE_TARJAN_H_

#include <algorithm>

#include "Allocator.h"

template<class T>
class Node {
 public:
  allocator::set<Node<T>*> references_in;
  allocator::set<Node<T>*> references_out;
  size_t index;
  size_t lowlink;

  T* ptr;

  Node(T* ptr, Allocator<Node> allocator) : references_in(allocator), references_out(allocator),
      ptr(ptr) {};
  Node(Node&& rhs) = default;
  void Edge(Node<T>* ref) {
    references_out.emplace(ref);
    ref->references_in.emplace(this);
  }
  template<class F>
  void Foreach(F&& f) {
    for (auto& node: references_out) {
      f(node->ptr);
    }
  }
 private:
  DISALLOW_COPY_AND_ASSIGN(Node<T>);
};

template<class T>
using Graph = allocator::vector<Node<T>*>;

template<class T>
using SCC = allocator::vector<Node<T>*>;

template<class T>
using SCCList = allocator::vector<SCC<T>>;

template<class T>
class TarjanAlgorithm {
 public:
  TarjanAlgorithm(Allocator<void> allocator) : index_(0),
    stack_(allocator), components_(allocator) {}

  void Execute(Graph<T>& graph, SCCList<T>& out);
 private:
  static constexpr size_t UNDEFINED_INDEX = static_cast<size_t>(-1);
  void Tarjan(Node<T>* vertex, Graph<T>& graph);

  size_t index_;
  allocator::vector<Node<T>*> stack_;
  SCCList<T> components_;
};

template<class T>
void TarjanAlgorithm<T>::Execute(Graph<T>& graph, SCCList<T>& out) {
  stack_.clear();
  components_.clear();
  index_ = 0;
  for (auto& it: graph) {
    it->index = UNDEFINED_INDEX;
    it->lowlink = UNDEFINED_INDEX;
  }

  for (auto& it: graph) {
    if (it->index == UNDEFINED_INDEX) {
      Tarjan(it, graph);
    }
  }
  out.swap(components_);
}

template<class T>
void TarjanAlgorithm<T>::Tarjan(Node<T>* vertex, Graph<T>& graph) {
  assert(vertex->index == UNDEFINED_INDEX);
  vertex->index = index_;
  vertex->lowlink = index_;
  index_++;
  stack_.push_back(vertex);
  for (auto& it: vertex->references_out) {
    Node<T>* vertex_next = it;
    if (vertex_next->index == UNDEFINED_INDEX) {
      Tarjan(vertex_next, graph);
      vertex->lowlink = std::min(vertex->lowlink, vertex_next->lowlink);
    } else if (std::find(stack_.begin(), stack_.end(), vertex_next) != stack_.end()) {
      vertex->lowlink = std::min(vertex->lowlink, vertex_next->index);
    }
  }
  if (vertex->lowlink == vertex->index) {
    SCC<T> component{components_.get_allocator()};
    Node<T>* other_vertex;
    do {
      other_vertex = stack_.back();
      stack_.pop_back();
      component.push_back(other_vertex);
    } while (other_vertex != vertex && !stack_.empty());

    components_.emplace_back(component);
  }
}

template<class T>
void Tarjan(Graph<T>& graph, SCCList<T>& out) {
  TarjanAlgorithm<T> tarjan{graph.get_allocator()};
  tarjan.Execute(graph, out);
}

#endif // LIBMEMUNREACHABLE_TARJAN_H_
