/* 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:   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 { namespace modules{
    
class ModulesSolver;

/**
 * \brief An individual module specific information
 * \sa XreateManagerDecoratorModules, ModulesSolver, ModulesRegistry
 */
class ModuleRecord {
    FRIENDS_MODULES_TESTS
    friend class ModulesSolver;
    
public:
    void addRequest(const Expression& request);
    void addControllerPath(const std::string& path);
    void addDiscoveryPath(const std::string& path);
    void addProperty(const Expression& prop);
    
private:
    std::list<Expression>   __requests;
    std::list<std::string>  __controllers;
    std::list<std::string>  __discoveryPaths;
    std::list<Expression>   __properties;
    
public:
    std::string __path;
};

/** 
 * \brief A module's requirements resolver
 *  \sa XreateManagerDecoratorModules, ModuleRecord
 */
class ModulesSolver{
    FRIENDS_MODULES_TESTS
    
public:
    ModulesSolver(){}
    
    /** \brief Loads content of *controllers* into logic program for resolution */
    void loadControllers(const ModuleRecord& module);
    
    /** \brief Discovers specified path for existing modules and stores found modules' properties */
    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);
    
public:
    std::ostringstream __program;    
};    
}} //end namespace xreate::modules

#endif /* MODULES_H */
