/* 
 * File:   dfa.h
 * Author: pgess
 *
 * Created on June 27, 2016, 1:50 PM
 */

#ifndef DFA_H
#define DFA_H

#include "clasplayer.h"

namespace xreate {namespace analysis {

    struct SymbolAnonymous {
        SymbolAnonymous(unsigned int symbolId): id(symbolId){}
        
        unsigned int id;
        std::list<Expression> tags;
        ScopePacked scope;
        std::list<SymbolPacked> dependencies;
    };
    
    struct SymbolInvalid { };

    typedef boost::variant<SymbolInvalid, SymbolAnonymous, SymbolPacked> SymbolNode;
    
    class DFAGraph: public IAnalysisData{
            friend class VisitorAddTag;
            friend class VisitorAddLink;
            friend class VisitorGetDependencyConnection;
            friend class VisitorSetDependencyConnection;
            
            
        public:
            DFAGraph(ClaspLayer* engine): __clasp(engine){}
            
            SymbolPacked createAnonymousSymbol(const ScopePacked& scope);
            void addAnnotation(SymbolNode& identifier, Expression&& tag);
            void addConnection(const SymbolPacked& identifierTo, const SymbolNode& identifierFrom, DFGConnection link);
            void addDependencyConnection(SymbolNode& identifierTo, SymbolNode& identifierFrom);
            bool isConnected(const SymbolPacked& identifierTo, const SymbolPacked& identifierFrom);

            void print(std::ostringstream& output) const;
            
        private:
            typedef unsigned int EdgeId;
            std::vector<std::pair<SymbolPacked, SymbolPacked>> __edges;
            std::multimap<SymbolPacked, EdgeId> __outEdges;
            std::vector<DFGConnection> __data;
            std::multimap<SymbolPacked, Expression> __tags;
            std::multimap<SymbolPacked, SymbolPacked> __dependencies;

            unsigned int __countAnonymousSymbols=0;
            ClaspLayer* __clasp;
    };
}}

#endif /* DFA_H */

