/*
 * InputFileRegistry.hpp
 *
 *  Created on: 25. 5. 2018
 *	  Author: Jan Travnicek
 */

#ifndef _INPUT_FILE_REGISTRY_HPP_
#define _INPUT_FILE_REGISTRY_HPP_

#include <alib/memory>
#include <alib/string>
#include <alib/map>
#include <alib/functional>

#include <exception/CommonException.h>
#include <abstraction/OperationAbstraction.hpp>

namespace abstraction {

class InputFileRegistry {
	class Entry {
	public:
		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( const std::string & type, const ext::vector < std::string > & templateParams ) const = 0;

		virtual ~Entry ( ) = default;
	};

	class EntryImpl : public Entry {
		std::function < std::shared_ptr < abstraction::OperationAbstraction > ( const std::string & type, const ext::vector < std::string > & templateParams ) > m_callback;
	public:
		EntryImpl ( std::shared_ptr < abstraction::OperationAbstraction > ( * callback ) ( const std::string & type, const ext::vector < std::string > & templateParams ) ) : m_callback ( callback ) {
		}

		std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( const std::string & type, const ext::vector < std::string > & templateParams ) const override;
	};

	static ext::map < std::string, std::unique_ptr < Entry > > & getEntries ( );

public:
	static void registerInputFileHandler ( const std::string & fileType, std::shared_ptr < abstraction::OperationAbstraction > ( * callback ) ( const std::string & type, const ext::vector < std::string > & templateParams ) );

	static void unregisterInputFileHandler ( const std::string & fileType );

	static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( const std::string & fileType, const std::string & type, const ext::vector < std::string > & templateParams );
};

} /* namespace abstraction */

#endif /* _INPUT_FILE_REGISTRY_HPP_ */
