#pragma once
#include "../http/request.hpp"
#include "../http/response.hpp"
#include "../logger.hpp"
#include "../scheduler.hpp"
#include "base.hpp"
#include <memory>
#include <string>
#include <vector>

namespace Middleware
{
	struct MiddlewareResult
	{
		bool const writeResult;
		int const socketFd;

		MiddlewareResult(bool const writeResult, int const socketFd);
	};

	class Middleware
	{
	private:
		Logger & logger;
		std::vector<std::unique_ptr<BaseMiddleware>> middlewares;
		std::map<int, std::unique_ptr<State>> socketFdToStateMap;
		std::map<int, int> eventFdToSocketFdMap;

		Middleware(Logger & logger);

		MiddlewareResult Loop(State & state, ScheduleHelper & scheduleHelper);

	public:
		MiddlewareResult Start(int const socketFd, ScheduleHelper & scheduleHelper, Http::Request const & request, Http::Response & response);
		MiddlewareResult Continue(int const fd, ScheduleHelper & scheduleHelper);

		void UseMiddleware(std::unique_ptr<BaseMiddleware> && middleware);

		static Middleware CreateWithStaticFile(Logger & logger, std::string const & rootDirectory);
	};
}