#ifndef  PASSMANAGER_H
#define PASSMANAGER_H

#include <string>
#include <map>

//stdio external
struct _IO_FILE;
typedef struct _IO_FILE FILE;

class Scanner;

namespace xreate {
class AbstractPassBase;
class ClaspLayer;
class LLVMLayer;
class AST;

enum class PassId {
	CFGPass,
	CompilePass,
	DFGPass,
	EnvironmentTestsPass,
	LoggerPass,
	AdhocPass,
	RulesPass,
        InterpretationPass
};

class PassManager
{
public:
    ~PassManager();
    void*run();
    void runWithoutCompilation();
    void executePasses();
    void registerPass(AbstractPassBase* pass, const PassId& id, AbstractPassBase* prerequisite=nullptr);
    AbstractPassBase* getPassById(const PassId& id);
    bool isPassRegistered(const PassId& id);
    static PassManager* prepareForCode(std::string&& code);
    static PassManager* prepareForCode(FILE* code);

    ClaspLayer* clasp;
    LLVMLayer* llvm;
    AST* root;
private:
    //typedef std::multimap<PassFilter, ASTPass*> FILTERS_STORAGE;
    //FILTERS_STORAGE __filters;
    std::map<PassId, AbstractPassBase*> __passes;
    std::multimap<AbstractPassBase*,  AbstractPassBase*> __passDependencies;
    bool flagIsProcessed = false;

    static PassManager* prepareForCode(Scanner* code);
}; }

#endif
