/*
Espe | Ein schlichtes Werkzeug zur Mitglieder-Verwaltung | Backend
Copyright (C) 2024 Christian Fraß

This program 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.

This program 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 this program. If not, see 
<https://www.gnu.org/licenses/>. 
 */

namespace _espe.api
{
	
	/**
	 * @todo zu plankton auslagern?
	 */
	type type_stuff = {
        version: (null | string);
        headers: Record<string, string>;
        path_parameters: Record<string, string>;
        query_parameters: Record<string, string>;
    };
    
    
	/**
	 */
	export async function session_from_stuff(
		stuff : {headers : Record<string, string>;}
	) : Promise<{key : string; value : lib_plankton.session.type_session}>
	{
		const key : string = (stuff.headers["X-Session-Key"] || stuff.headers["X-Session-Key".toLowerCase()]);
		const value : lib_plankton.session.type_session = await lib_plankton.session.get(key);
		return {"key": key, "value": value};
	}
	
	
	/**
	 */
	/*
	export function restriction_disjunction(
		left : lib_plankton.rest.type_restriction<any>,
		right : lib_plankton.rest.type_restriction<any>
	) : lib_plankton.rest.type_restriction<any>
	{
		return (
			(stuff) => Promise.any<boolean>(
				[
					left(stuff),
					right(stuff),
				]
			)
		);
	}
	 */
	
	
	/**
	 */
	export const restriction_none : lib_plankton.rest.type_restriction<any> = (
		(stuff) => Promise.resolve<boolean>(true)
	);
	
	
	/**
	 */
	export const restriction_logged_in : lib_plankton.rest.type_restriction<any> = (
		(stuff) => (
			session_from_stuff(stuff)
			.then(() => Promise.resolve<boolean>(true))
			.catch(() => Promise.resolve<boolean>(false))
		)
	);
	
	
	/**
	 */
	export function restriction_verification(
		extract_data : ((stuff : type_stuff) => any),
		extract_verification : ((stuff : type_stuff) => string)
	) : lib_plankton.rest.type_restriction<any>
	{
		return (
			(stuff) => _espe.helpers.verification_check(
				extract_data(stuff),
				extract_verification(stuff)
			)
		);
	}

	
	/**
	 */
	export function register<type_input, type_output>(
		rest_subject : lib_plankton.rest.type_rest,
		http_method : lib_plankton.http.enum_method,
		path : string,
		options : {
			active ?: ((version : string) => boolean);
			restriction ?: (null | lib_plankton.rest.type_restriction<type_input>);
			execution ?: lib_plankton.rest.type_execution<type_input, type_output>;
			title ?: (null | string);
			description ?: (null | string);
			query_parameters ?: Array<
				{
					name : string;
					description : (null | string);
					required : boolean;
				}
			>;
			input_schema ?: ((version: (null | string)) => lib_plankton.rest.type_oas_schema);
			output_schema ?: ((version: (null | string)) => lib_plankton.rest.type_oas_schema);
			request_body_mimetype ?: string;
			request_body_decode ?: ((http_request_body : Buffer, http_request_header_content_type : (null | string)) => any);
			response_body_mimetype ?: string;
			response_body_encode ?: ((output : any) => Buffer);
		} = {}
	) : void
	{
		options = Object.assign(
			{
			},
			options
		);
		lib_plankton.rest.register<type_input, type_output>(
			rest_subject,
			http_method,
			(_espe.conf.get().server.path_base + path),
			options
		);
	}
	
}
