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

#ifndef _OUTPUT_FILE_REGISTRY_HPP_
#define _OUTPUT_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 OutputFileRegistry {
	class Entry {
	public:
		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( const std::string & typehint ) const = 0;

		virtual ~Entry ( ) = default;
	};

	class EntryImpl : public Entry {
		std::function < std::shared_ptr < abstraction::OperationAbstraction > ( const std::string & typehint ) > m_callback;
	public:
		EntryImpl ( std::shared_ptr < abstraction::OperationAbstraction > ( * callback ) ( const std::string & typehint ) ) : m_callback ( callback ) {
		}

		std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( const std::string & typehint ) const override;
	};

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

public:
	static void registerOutputFileHandler ( const std::string & fileType, std::shared_ptr < abstraction::OperationAbstraction > ( * callback ) ( const std::string & typehint ) );

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

	static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( const std::string & fileType, const std::string & typehint );
};

} /* namespace abstraction */

#endif /* _OUTPUT_FILE_REGISTRY_HPP_ */
