#pragma once
//stl
#include <iostream>
#include <memory>
#include <filesystem>
//robotics
#include <robotics/logger.hpp>
//local
#include "../response/response.hpp"

/**
 * @brief 在处理 HTTP 请求前执行预处理逻辑，用于判断请求是由控制器处理还是访问文件，并进行权限验证和异常处理。
 */
struct http_before {
	/**
	 * @brief 在处理 HTTP 请求前执行预处理逻辑，包括路径校验、资源存在性检查和权限认证。
	 * @param controller_action 指向控制器动作的智能指针，用于描述当前请求对应的控制器行为。
	 * @param request HTTP 请求对象，包含请求的路径和相关信息。
	 * @param response HTTP 响应对象，用于生成和返回响应内容。
	 * @return 如果存在有效的控制器动作则返回 true，否则返回 false。
	 */
	bool before(std::shared_ptr<v3::mvc::controller_action> controller_action, http::web_request& request, http::web_response& response) {
		if (request.path() == "/") {
			throw default_page_response();
		}
		if (!controller_action) {
			std::filesystem::path root_directory = v3::mvc::http_context::current()->root_directory;
			std::filesystem::path route = std::string(request.path().begin(), request.path().end());
			root_directory.make_preferred();
			root_directory /= route.make_preferred().relative_path();
			if (!std::filesystem::exists(root_directory)) {
				throw not_found_response();
			}
		}
		else {
			if (controller_action->authen && !v3::mvc::http_context::current()->authen()) {
				if (!controller_action->authen_jump.empty()) {
					throw v3::mvc::jump_response(controller_action->authen_jump);
				}
				throw default_page_response();
			}
			else if (v3::mvc::http_context::current()->authen()) {
				if (!controller_action->authen_jump.empty()) {
					throw v3::mvc::jump_response(controller_action->authen_jump);
				}
			}
		}
		return (bool)controller_action;
	}
};
/**
 * @brief 处理 HTTP 请求时发生的错误，并记录错误信息。
 */
struct http_error {
	/**
	 * @brief 处理 HTTP 请求时记录错误并生成内部服务器错误响应页面。
	 * @param err 要记录的错误信息字符串。
	 * @param request 当前的 HTTP 请求对象。
	 * @param response 用于生成和发送 HTTP 响应的对象。
	 */
	void error(std::string const& err, http::web_request& request, http::web_response& response) {
		robotics::v3::mvc::web_base_response().fill_page("internal server error.", http::status::internal_server_error);
		LOG_ERROR << err;
	}
};
/**
 * @brief 在处理 HTTP 请求后执行的回调函数。
 */
struct http_after {
	/**
	 * @brief 在处理 HTTP 请求后执行的回调函数。
	 * @param request 对当前 HTTP 请求的引用。
	 * @param response 对当前 HTTP 响应的引用。
	 */
	void after(http::web_request& request, http::web_response& response) {

	}
};