#pragma once

#include <psemek/bt/node.hpp>
#include <psemek/bt/assert.hpp>

namespace psemek::bt
{

	template <typename Tree, typename ConditionFn>
	struct condition_node;

	template <typename Time, typename Event, typename ... Args, typename ConditionFn>
	struct condition_node<tree<Time, Event, Args...>, ConditionFn>
		: node<tree<Time, Event, Args...>>
	{
		using tree_type = tree<Time, Event, Args...>;
		using node_type = node<tree_type>;
		using typename node_type::finished;
		using typename node_type::status;

		condition_node(ConditionFn && condition_fn)
			: condition_fn_(std::move(condition_fn))
		{}

		status update(Time, Args ... args) override
		{
			try
			{
				return finished{condition_fn_(args...)};
			}
			catch (assertion_failed_exception const &)
			{
				return finished{false};
			}
		}

	private:
		ConditionFn condition_fn_;
	};

	template <typename Tree, typename ConditionFn>
	node_ptr<Tree> condition(ConditionFn && condition_fn)
	{
		return std::make_unique<condition_node<Tree, ConditionFn>>(std::move(condition_fn));
	}

}
