#ifndef wasm_analysis_monotone_analyzer_impl_h
#define wasm_analysis_monotone_analyzer_impl_h

#include <iostream>
#include <unordered_map>

#include "monotone-analyzer.h"
#include "support/unique_deferring_queue.h"

namespace wasm::analysis {

template<Lattice L, TransferFunction TxFn>
inline MonotoneCFGAnalyzer<L, TxFn>::MonotoneCFGAnalyzer(L& lattice,
                                                         TxFn& txfn,
                                                         CFG& cfg)
  : lattice(lattice), txfn(txfn), cfg(cfg),
    states(cfg.size(), lattice.getBottom()) {}

template<Lattice L, TransferFunction TxFn>
inline void
MonotoneCFGAnalyzer<L, TxFn>::evaluateFunctionEntry(Function* func) {
  txfn.evaluateFunctionEntry(func, states[0]);
}
template<Lattice L, TransferFunction TxFn>
inline void MonotoneCFGAnalyzer<L, TxFn>::evaluateFunctionExit(Function* func) {
  for (size_t i = 0; i < cfg.size(); i++) {
    if (cfg[i].isExit()) {
      txfn.evaluateFunctionExit(func, states[i]);
      break;
    }
  }
}

template<Lattice L, TransferFunction TxFn>
inline void MonotoneCFGAnalyzer<L, TxFn>::evaluate() {
  UniqueDeferredQueue<Index> worklist;

  // Start with all blocks on the work list. TODO: optimize the iteration order
  // using e.g. strongly-connected components.
  for (Index i = 0; i < cfg.size(); ++i) {
    worklist.push(i);
  }

  while (!worklist.empty()) {
    // The index of the block we will analyze.
    Index i = worklist.pop();

    // Apply the transfer function to the input state to compute the output
    // state, then propagate the output state to the dependent blocks.
    auto state = states[i];
    for (const auto* dep : txfn.transfer(cfg[i], state)) {
      // If the input state for the dependent block changes, we need to
      // re-analyze it.
      if (lattice.join(states[dep->getIndex()], state)) {
        worklist.push(dep->getIndex());
      }
    }
  }
}

template<Lattice L, TransferFunction TxFn>
inline void MonotoneCFGAnalyzer<L, TxFn>::collectResults() {
  for (Index i = 0, size = cfg.size(); i < size; ++i) {
    // The transfer function generates the final set of states and uses it to
    // produce useful information. For example, in reaching definitions
    // analysis, these final states are used to populate a mapping of
    // local.get's to a set of local.set's that affect its value.
    txfn.collectResults(cfg[i], states[i]);
  }
}

// Currently prints both the basic information and intermediate states of each
// BlockState.
template<Lattice L, TransferFunction TxFn>
inline void MonotoneCFGAnalyzer<L, TxFn>::print(std::ostream& os) {
  os << "CFG Analyzer" << std::endl;
  for (Index i = 0, size = cfg.size(); i < size; ++i) {
    os << "CFG Block: " << cfg[i].getIndex() << std::endl;
    os << "Input State: ";
    states[i].print(os);
    for (auto& pred : cfg[i].preds()) {
      os << " " << pred->getIndex();
    }
    os << std::endl << "Successors:";
    for (auto& succ : cfg[i].succs()) {
      os << " " << succ->getIndex();
    }
    os << "\n";
    txfn.print(os, cfg[i], states[i]);
  }
  os << "End\n";
}

} // namespace wasm::analysis

#endif // wasm_analysis_monotone_analyzer_impl_h
