
namespace _zeitbild.api
{
	
	/**
	 */
	export function register_caldav_get(
		rest_subject : lib_plankton.rest_caldav.type_rest
	) : void
	{
		register<
			null,
			/*
			(
				null
				|
				string
				|
				lib_plankton.ical.type_vcalendar
			)
			 */
			(
				null
				|
				lib_plankton.xml.type_node_data
			)
		>(
			rest_subject,
			lib_plankton.caldav.enum_method.report,
			"/caldav/project/:id",
			{
				"description": "trägt Veranstaltungen aus verschiedenen Kalendern zusammen im ical-Format",
				"query_parameters": () => ([
					{
						"name": "from",
						"required": false,
						"description": "UNIX timestamp",
					},
					{
						"name": "to",
						"required": false,
						"description": "UNIX timestamp",
					},
					{
						"name": "calendar_ids",
						"required": false,
						"description": "comma separated",
					},
					{
						"name": "auth",
						"required": true,
						"description": "",
					},
				]),
				"output_schema": () => ({
					"nullable": false,
					"type": "string",
				}),
				/*
				"response_body_mimetype": "text/calendar",
				"response_body_encode": (output) => (
					(output === null)
					?
					null
					:
					Buffer.from(
						(typeof(output) === "string")
						?
						output
						:
						lib_plankton.ical.ics_encode(output)
					)
				),
				 */
				"response_body_mimetype": "text/xml",
				"response_body_encode": output => Promise.resolve<Buffer>(
					Buffer.from(
						lib_plankton.xml.get_node_logic(output).compile(0)
					)
				),
				"restriction": restriction_none,
				/**
				 * @todo use stuff.path_parameters["id"]
				 */
				"execution": async (stuff) => {
					const user_id : (null | type_user_id) = await _zeitbild.api.web_auth(
						stuff.headers["Authorization"]
						??
						stuff.headers["authorization"]
						??
						null
					);
					if (user_id === null) {
						return Promise.resolve(
							{
								"status_code": 401,
								"data": null,
								"extra_headers": {
									"WWW-Authenticate": "Basic realm=Restricted",
								}
							}
						);
					}
					else {
						const from : lib_plankton.pit.type_pit = (
							("from" in stuff.query_parameters)
							?
							parseInt(stuff.query_parameters["from"])
							:
							lib_plankton.pit.shift_week(
								lib_plankton.pit.now(),
								-2
							)
						);
						const to : lib_plankton.pit.type_pit = (
							("to" in stuff.query_parameters)
							?
							parseInt(stuff.query_parameters["to"])
							:
							lib_plankton.pit.shift_week(
								lib_plankton.pit.now(),
								+6
							)
						);
						const calendar_ids_wanted : (null | Array<_zeitbild.type_calendar_id>) = (
							(
								("calendar_ids" in stuff.query_parameters)
								&&
								(stuff.query_parameters["calendar_ids"] !== null)
							)
							?
							lib_plankton.call.convey(
								stuff.query_parameters["calendar_ids"],
								[
									(x : string) => x.split(","),
									(x : Array<string>) => x.map(parseInt),
									(x : Array<int>) => x.filter(y => (! isNaN(y)))
								]
							)
							:
							null
						);
						
						return (
							_zeitbild.service.calendar.gather_events(
								calendar_ids_wanted,
								from,
								to,
								user_id
							)
							.then(
								(data) => Promise.resolve(
									{
										"status_code": 200,
										/*
										"data": _zeitbild.helpers.ical_vcalendar_from_own_event_list(
											data.map(entry => entry.event_object)
										)
										 */
										"data": lib_plankton.webdav.data_multistatus_encode_xml(
											{
												"responses": (
													/**
													 * @todo find proper solution for null values
													 */
													data
													.filter(
														entry => (entry.event_id !== null)
													)
													.map(
														entry => ({
															"href": lib_plankton.string.coin(
																"/caldav/project/{{calendar_id}}/{{event_id}}",
																{
																	"calendar_id": stuff.path_parameters["id"],
																	"event_id": (entry.event_id ?? 0).toFixed(0),
																}
															),
															"body": {
																"propstats": [
																	{
																		"prop": [
																			{
																				"name": "C:calendar-data",
																				"value": {
																					"kind": "primitive",
																					"data": lib_plankton.ical.ics_encode(
																						/*
																						{
																							"version": "2.0",
																							"prodid": "zeitbild",
																							"vevents": [],
																							"method": "publish",
																						}
																						 */
																						_zeitbild.helpers.ical_vcalendar_from_own_event_list(
																							data
																							.map(
																								entry => entry.event_object
																							)
																						)
																					)
																				}
																			},
																		],
																		"status": "HTTP/1.1 200 OK",
																		"description": null,
																	}
																]
															},
															"description": null
														})
													)
												),
												"description": null
											}
										)
									}
								)
							)
							.catch(
								(reason) => Promise.resolve(
									{
										"status_code": 403,
										"data": /*String(reason)*/null,
									}
								)
							)
						);
					}
				}
			}
		);
	}
	
}
