/* 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 "clasplayer.h"

namespace xreate {namespace cfa {

    /** \brief Represents CFA analysis data produced by CFAPass */
    class CFAGraph: public IAnalysisReport {
    public:
        typedef boost::bimap<ScopePacked,  boost::bimaps::multiset_of<unsigned int>> PARENT_FUNCTION_RELATIONS;
        PARENT_FUNCTION_RELATIONS __parentFunctionRelations;
        std::map<ScopePacked, ScopePacked> __parentScopeRelations;
        
        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 > __nodesFunction;
        std::multimap<unsigned int, Expression> __functionTags;
        std::multimap<ScopePacked, Expression> __scopeTags;
        std::multimap<ScopePacked, ContextRule> __contextRules;
        
        void print(std::ostringstream& output) const override;
        CFAGraph(ClaspLayer* engine): __clasp(engine){}
        
        void addFunctionAnnotations(const std::string& function, 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& scopeFrom, const std::string& functionTo);
        void addParentConnection(const ScopePacked& scope, const std::string& functionParent);
        void addParentConnection(const ScopePacked& scope, const ScopePacked& scopeParent);
        //        void addScopeRetIdentifier(const ScopePacked& scope, const SymbolPacked& identifier);
        
    private:
        ClaspLayer* __clasp;
        
        unsigned int registerNodeFunction(const std::string& fname);
        
    };
    
}} //end of namespace xreate::cfa

#endif /* CFAGRAPH_H */

