/* 
 * File:   modules.h
 * Author: pgess <v.melnychenko@xreate.org>
 *
 * Created on July 22, 2017, 5:11 PM
 */

#ifndef MODULES_H
#define MODULES_H

#include "ast.h"
#include <boost/bimap.hpp>

#ifndef FRIENDS_MODULES_TESTS
#define FRIENDS_MODULES_TESTS
#endif

namespace xreate {
class ModulesRegistry{
public:
    const std::string& getModuleNameByHash(unsigned int hash);
    unsigned int getModuleHash(const std::string& moduleName);
    
private:
    typedef boost::bimap<std::string, unsigned int> Hash;
    Hash __registry;
};

class ModulesSolver;

class ModuleRecord {
    FRIENDS_MODULES_TESTS
    friend class ModulesSolver;
    
public:
    void addModuleQuery(const Expression& query);
    void addControllerPath(const std::string& path);
    void addDiscoveryPath(const std::string& path);
    void addProperty(const Expression& prop);
    
private:
    std::list<Expression>   __queries;
    std::list<std::string>  __controllers;
    std::list<std::string>  __discoveries;
    std::list<Expression>   __properties;
    
public:
    std::string __path;
};

class ModulesSolver{
    FRIENDS_MODULES_TESTS
    
public:
    ModulesSolver(ModulesRegistry *registry): __registry(registry) {}
    
    void loadControllers(const ModuleRecord& module);
    void discoverModules(const ModuleRecord& moduleClient);
    
    void extractProperties(const ModuleRecord& module);
    void extractRequirements(const ModuleRecord& module);
    
    void add(const std::string& base);
    
    void init(const std::string& programBase, const ModuleRecord& module);
    std::list<std::string> run(const ModuleRecord& module);
    
private:
    ModulesRegistry* __registry;
    
public:
    std::ostringstream __program;    
};    
} //end namespace xreate

#endif /* MODULES_H */