/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 * 
 * File:   CFAGraph.h
 * Author: pgess <v.melnychenko@xreate.org>
 *
 * Created on June 27, 2016, 2:09 PM
 */

#ifndef CFAGRAPH_H
#define CFAGRAPH_H

#include "transcendlayer.h"

namespace xreate{
namespace cfa{

/** \brief Represents CFA analysis data produced by CFAPass 
 */
class CFAGraph: public IAnalysisReport{
  friend class TemporalSeqGraph;
public:
  typedef boost::bimap<ScopePacked, boost::bimaps::multiset_of<unsigned int>> PARENT_FUNCTION_RELATIONS;
  PARENT_FUNCTION_RELATIONS __parentFnRelation;
  std::map<ScopePacked, ScopePacked> __parentScopeRelation;

  typedef boost::bimap<
  boost::bimaps::multiset_of<ScopePacked>,
  boost::bimaps::multiset_of<unsigned int>,
  boost::bimaps::set_of_relation<>
  > CALL_RELATIONS;

  CALL_RELATIONS __callRelations;

  boost::bimap<unsigned int, std::string> __fnNodes;
  std::multimap<unsigned int, Expression> __fnTags;
  std::multimap<ScopePacked, Expression> __scopeTags;
  std::multimap<ScopePacked, ContextRule> __contextRules;
  unsigned int __scopesCount = 0;

  void print(std::ostringstream &output) const override;

  CFAGraph(TranscendLayer* engine): __transcend(engine){ }

  void addFunctionAnnotations(const std::string &fn, const std::map<std::string, Expression> &tags);
  void addScopeAnnotations(const ScopePacked &scope, const std::vector<Expression> &tags);
  void addContextRules(const ScopePacked &scope, const std::vector<Expression> &rules);
  void addCallConnection(const ScopePacked &callerScope, const std::string &calleeFn);
  void addParentConnection(const ScopePacked &scopeEntry, const std::string &fnParent);
  void addParentConnection(const ScopePacked &scopeChild, const ScopePacked &scopeParent);
  void addScope(CodeScope* scope);

private:
  TranscendLayer* __transcend;
  std::ostringstream __outputPrecomputed;

  unsigned int registerNodeFunction(const std::string &fname);
};



}
} //end of namespace xreate::cfa

#endif /* CFAGRAPH_H */

