#ifndef wasm_analysis_monotone_analyzer_impl_h
#define wasm_analysis_monotone_analyzer_impl_h

#include <iostream>
#include <unordered_map>

#include "monotone-analyzer.h"

namespace wasm::analysis {

// All states are set to the bottom lattice element using the lattice in this
// constructor.
template<typename Lattice>
inline BlockState<Lattice>::BlockState(const BasicBlock* underlyingBlock,
                                       Lattice& lattice)
  : cfgBlock(underlyingBlock), inputState(lattice.getBottom()) {}

// Prints out inforamtion about a CFG node's state, but not intermediate states.
template<typename Lattice>
inline void BlockState<Lattice>::print(std::ostream& os) {
  os << "CFG Block: " << cfgBlock->getIndex() << std::endl;
  os << "Input State: ";
  inputState.print(os);
  os << std::endl << "Predecessors:";
  for (auto pred : cfgBlock->preds()) {
    os << " " << pred.getIndex();
  }
  os << std::endl << "Successors:";
  for (auto succ : cfgBlock->succs()) {
    os << " " << succ.getIndex();
  }
  os << std::endl;
}

template<typename Lattice, typename TransferFunction>
inline MonotoneCFGAnalyzer<Lattice, TransferFunction>::MonotoneCFGAnalyzer(
  Lattice& lattice, TransferFunction& transferFunction, CFG& cfg)
  : lattice(lattice), transferFunction(transferFunction), cfg(cfg) {

  // Construct BlockStates for each BasicBlock.
  for (auto it = cfg.begin(); it != cfg.end(); it++) {
    stateBlocks.emplace_back(&(*it), lattice);
  }
}

template<typename Lattice, typename TransferFunction>
inline void
MonotoneCFGAnalyzer<Lattice, TransferFunction>::evaluateFunctionEntry(
  Function* func) {
  transferFunction.evaluateFunctionEntry(func, stateBlocks[0].inputState);
}

template<typename Lattice, typename TransferFunction>
inline void MonotoneCFGAnalyzer<Lattice, TransferFunction>::evaluate() {
  std::queue<const BasicBlock*> worklist;

  // Transfer function enqueues the work in some order which is efficient.
  transferFunction.enqueueWorklist(cfg, worklist);

  while (!worklist.empty()) {
    BlockState<Lattice>& currBlockState =
      stateBlocks[worklist.front()->getIndex()];
    worklist.pop();

    // For each expression, applies the transfer function, using the expression,
    // on the state of the expression it depends upon (here the next expression)
    // to arrive at the expression's state. The beginning and end states of the
    // CFG block will be updated.
    typename Lattice::Element outputState = currBlockState.inputState;
    transferFunction.transfer(currBlockState.cfgBlock, outputState);

    // Propagate state to dependents of currBlockState.
    for (auto& dep : transferFunction.getDependents(currBlockState.cfgBlock)) {
      // If we need to change the input state of a dependent, we need
      // to enqueue the dependent to recalculate it.
      if (stateBlocks[dep.getIndex()].inputState.makeLeastUpperBound(
            outputState)) {
        worklist.push(&dep);
      }
    }
  }
}

template<typename Lattice, typename TransferFunction>
inline void MonotoneCFGAnalyzer<Lattice, TransferFunction>::collectResults() {
  for (BlockState currBlockState : stateBlocks) {
    typename Lattice::Element inputStateCopy = currBlockState.inputState;

    // 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.
    transferFunction.collectResults(currBlockState.cfgBlock, inputStateCopy);
  }
}

// Currently prints both the basic information and intermediate states of each
// BlockState.
template<typename Lattice, typename TransferFunction>
inline void
MonotoneCFGAnalyzer<Lattice, TransferFunction>::print(std::ostream& os) {
  os << "CFG Analyzer" << std::endl;
  for (auto state : stateBlocks) {
    state.print(os);
    typename Lattice::Element temp = state.inputState;
    transferFunction.print(os, state.cfgBlock, temp);
  }
  os << "End" << std::endl;
}

} // namespace wasm::analysis

#endif // wasm_analysis_monotone_analyzer_impl_h
