#ifndef MDD_PROCESSORBASE_H
#define MDD_PROCESSORBASE_H

#include <list>
#include "Input.h"
#include "IProcessor.h"
#include "HandlerModule.h"

namespace mdd {
    class ProcessorBase : public IProcessor{
    private:
        std::string _prefix;
        std::string _type;
        int _appendix;

        std::vector<std::shared_ptr<Input>> _processor_inputs;
        std::vector<std::shared_ptr<Output>> _processor_outputs;

        std::vector<HandlerModule<IInput>> _module_inputs;
        std::vector<HandlerModule<IOutput>> _module_outputs;
        std::vector<std::shared_ptr<IModule>> _modules;

    protected:
        int addProcesorInput(const std::string& type, const json& value,
        const std::function<bool(const json&)>& verification = [](
                const json&) { return true; });
        int addProcessorOutput(const std::string& type, const json& initial);
        std::shared_ptr<IOutput> getProcessorOutput(int handle);
        std::shared_ptr<IInput> getProcessorInput(int handle);
        std::shared_ptr<IModule> getModule(int handle);

    public:
        std::string getID() override ;
        std::string setType(std:: string type) override;
        std::string getType() override;
        std::string setPrefix(std::string prefix) override;
        std::string setAppendix(int appendix) override;
        void updateID() override ;

        std::string addModule(std::shared_ptr<IModule> module) override ;
        std::string addModuleInput(std::string module_ID, std::string input_ID);
        std::string addModuleInput(std::shared_ptr<IModule> module, std::shared_ptr<IInput> input);
        std::string addModuleOutput(std::string module_ID, std::string output_ID);
        std::string addModuleOutput(std::shared_ptr<IModule> module, std::shared_ptr<IOutput> output);

        std::vector<std::string> getInputs() override;
        std::vector<std::string> getOutputs() override;
        std::vector<std::string> getModules() override;

        std::vector<std::string> getInputIDs();
        std::vector<std::string> getOutputIDs();
        std::vector<std::string> getModuleIDs();

        std::shared_ptr<IOutput> getOutput(std::string output_id) override;
        std::shared_ptr<IInput> getInput(std::string input_id) override;
        std::shared_ptr<IModule> getModule(std::string module_id) override;
    };
}
#endif
