#pragma once

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

namespace psemek::bt
{

	template <typename Tree, typename ProcessFn>
	struct process_node;

	template <typename Time, typename Event, typename ... Args, typename ProcessFn>
	struct process_node<tree<Time, Event, Args...>, ProcessFn>
		: 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;

		process_node(ProcessFn && process_fn)
			: process_fn_(std::move(process_fn))
		{}

		void start(Args ...) override
		{}

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

		bool event(Event const &, Args ...) override
		{
			return false;
		}

	private:
		ProcessFn process_fn_;
	};

	template <typename Tree, typename ProcessFn>
	node_ptr<Tree> process(ProcessFn && process_fn)
	{
		return std::make_unique<process_node<Tree, ProcessFn>>(std::move(process_fn));
	}

}
