#include <alib/typeinfo>

#include "InputFileTypeRegistration.hpp"

#include <registry/XmlRegistry.h>

#include <abstraction/XmlTokensParserAbstraction.hpp>
#include <abstraction/WrapperAbstraction.hpp>
#include <abstraction/PackingAbstraction.hpp>

#include <registry/Registry.h>

namespace {

	std::shared_ptr < abstraction::OperationAbstraction > dummy ( const std::string & typehint, const ext::vector < std::string > & templateParams ) {
		if ( typehint == "set" || typehint == "Set" ) {
			ext::vector < std::shared_ptr < abstraction::OperationAbstraction > > abstractions;

			abstractions.push_back ( std::make_shared < abstraction::XmlTokensParserAbstraction > ( ) );
			abstractions.push_back ( abstraction::XmlRegistry::getXmlContainerParserAbstraction ( "Set", templateParams [ 0 ] ) );

			std::shared_ptr < abstraction::PackingAbstraction < 1 > > res = std::make_shared < abstraction::PackingAbstraction < 1 > > ( std::move ( abstractions ), 1 );
			res->setInnerConnection ( 0, 1, 0 );
			res->setOuterConnection ( 0, 0, 0 );

			return res;
		} else {
			ext::vector < std::shared_ptr < abstraction::OperationAbstraction > > abstractions;

			abstractions.push_back ( std::make_shared < abstraction::XmlTokensParserAbstraction > ( ) );

			auto xmlParserAbstractionFinder = [ = ] ( const ext::deque < sax::Token > & tokens ) {
				std::string type;
				if ( typehint.empty ( ) )
					type = tokens [ 0 ].getData ( );
				else
					type = typehint;

				return abstraction::XmlRegistry::getXmlParserAbstraction ( type );
			};

			abstractions.push_back ( std::make_shared < abstraction::WrapperAbstraction < const ext::deque < sax::Token > & > > ( xmlParserAbstractionFinder ) );

			std::shared_ptr < abstraction::PackingAbstraction < 1 > > res = std::make_shared < abstraction::PackingAbstraction < 1 > > ( std::move ( abstractions ), 1 );
			res->setInnerConnection ( 0, 1, 0 );
			res->setOuterConnection ( 0, 0, 0 );

			return res;
		}
	}

	std::shared_ptr < abstraction::OperationAbstraction > dummy2 ( const std::string &, const ext::vector < std::string > & ) {
		ext::vector < std::string > templateParams;
		ext::vector < std::string > paramTypes { ext::to_string < std::string > ( ) };
		abstraction::AlgorithmCategories::AlgorithmCategory category = abstraction::AlgorithmCategories::AlgorithmCategory::NONE;
		ext::vector < abstraction::TypeQualifiers::TypeQualifierSet > paramTypeQualifiers { abstraction::TypeQualifiers::typeQualifiers < const std::string & > ( ) };

		return abstraction::Registry::getAlgorithmAbstraction ( "cli::builtin::ReadFile", templateParams, paramTypes, paramTypeQualifiers, category );
	}

auto xmlInputFileHandler = registration::InputFileRegister ( "xml", dummy );
auto fileInputFileHandler = registration::InputFileRegister ( "file", dummy2 );

}
