#include <ast/statements/SingleStatement.h>
#include <ast/Arg.h>
#include <common/EvalHelper.h>
#include <common/AlgorithmCategories.hpp>

namespace cli {

SingleStatement::SingleStatement ( std::unique_ptr < Arg > name, ext::vector < std::unique_ptr < cli::Arg > > templateParams, ext::vector < std::shared_ptr < Statement > > params, std::unique_ptr < CategoryOption > category ) : m_name ( std::move ( name ) ), m_templateParams ( std::move ( templateParams ) ), m_params ( std::move ( params ) ), m_category ( std::move ( category ) ) {
}

std::shared_ptr < abstraction::Value > SingleStatement::translateAndEval ( const std::shared_ptr < abstraction::Value > & prev, Environment & environment ) const {
	ext::vector < std::shared_ptr < abstraction::Value > > params;
	for ( const std::shared_ptr < Statement > & param : m_params ) {
		std::shared_ptr < abstraction::Value > translatedParam = param->translateAndEval ( prev, environment );
		environment.holdTemporary ( translatedParam );
		params.push_back ( translatedParam );
	}

	std::string name = m_name->eval ( environment );

	ext::vector < std::string > templateParams;
	for ( const std::unique_ptr < cli::Arg > & templateParam : m_templateParams )
		templateParams.push_back ( templateParam->eval ( environment ) );

	abstraction::AlgorithmCategories::AlgorithmCategory category = abstraction::AlgorithmCategories::AlgorithmCategory::NONE;
	if ( m_category )
		category = m_category->getCategory ( );

	return abstraction::EvalHelper::evalAlgorithm ( environment, name, templateParams, params, category );
}

} /* namespace cli */
