/*
	This file is part of Fennix Kernel.

	Fennix Kernel is free software: you can redistribute it and/or
	modify it under the terms of the GNU General Public License as
	published by the Free Software Foundation, either version 3 of
	the License, or (at your option) any later version.

	Fennix Kernel is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/

#pragma once

#include <convert.h>
#include <task.hpp>
#include <debug.h>
#include <smp.hpp>

extern Tasking::Task *TaskManager;

namespace std
{
	class thread
	{
	private:
		Tasking::TCB *Task = nullptr;

	public:
		thread() = default;
		thread(const thread &) = delete;
		thread(thread &&) = delete;
		thread &operator=(const thread &) = delete;
		thread &operator=(thread &&) = delete;

		template <class Function, class... Args>
		explicit thread(Function &&f, Args &&...args)
		{
			Task = TaskManager->CreateThread(thisProcess, (Tasking::IP)f);
			Task->SYSV_ABI_Call(std::forward<Args>(args)...);
		}

		~thread()
		{
			if (Task)
				Task->SendSignal(SIGKILL);
		}

		void join()
		{
			TaskManager->WaitForThread(Task);
		}

		bool joinable() const
		{
			return Task != nullptr;
		}

		void detach()
		{
			Task = nullptr;
		}

		void swap(thread &other) noexcept
		{
			Tasking::TCB *temp = Task;
			Task = other.Task;
			other.Task = temp;
		}

		Tasking::TCB *native_handle()
		{
			return Task;
		}
	};
}
