
namespace _zeitbild.repository.resource
{
	
	/**
	 */
	var _local_resource_core_store : (
		null
		|
		lib_plankton.storage.type_store<
			int,
			Record<string, any>,
			{},
			lib_plankton.storage.type_sql_table_autokey_search_term,
			Record<string, any>
		>
	) = null;
	
	
	/**
	 */
	var _local_resource_event_store : (
		null
		|
		lib_plankton.storage.type_store<
			int,
			Record<string, any>,
			{},
			lib_plankton.storage.type_sql_table_autokey_search_term,
			Record<string, any>
		>
	) = null;
	
	
	/**
	 */
	var _caldav_resource_store : (
		null
		|
		lib_plankton.storage.type_store<
			int,
			Record<string, any>,
			{},
			lib_plankton.storage.type_sql_table_autokey_search_term,
			Record<string, any>
		>
	) = null;
	
	
	/**
	 */
	var _resource_core_store : (
		null
		|
		lib_plankton.storage.type_store<
			_zeitbild.type.resource_id,
			Record<string, any>,
			{},
			lib_plankton.storage.type_sql_table_autokey_search_term,
			Record<string, any>
		>
	) = null;
	
	
	/**
	 */
	function get_local_resource_core_store(
	) : lib_plankton.storage.type_store<
		int,
		Record<string, any>,
		{},
		lib_plankton.storage.type_sql_table_autokey_search_term,
		Record<string, any>
	>
	{
		if (_local_resource_core_store === null) {
			_local_resource_core_store = lib_plankton.storage.sql_table_autokey_store(
				{
					"database_implementation": _zeitbild.database.get_implementation(),
					"table_name": "local_resources",
					"key_name": "id",
				}
			);
		}
		else {
			// do nothing
		}	
		return _local_resource_core_store;
	}
	
	
	/**
	 */
	function get_local_resource_event_store(
	) : lib_plankton.storage.type_store<
		int,
		Record<string, any>,
		{},
		lib_plankton.storage.type_sql_table_autokey_search_term,
		Record<string, any>
	>
	{
		if (_local_resource_event_store === null) {
			_local_resource_event_store = lib_plankton.storage.sql_table_autokey_store(
				{
					"database_implementation": _zeitbild.database.get_implementation(),
					"table_name": "local_resource_events",
					"key_name": "id",
				}
			);
		}
		else {
			// do nothing
		}	
		return _local_resource_event_store;
	}
	
	
	/**
	 */
	function get_caldav_resource_store(
	) : lib_plankton.storage.type_store<
		int,
		Record<string, any>,
		{},
		lib_plankton.storage.type_sql_table_autokey_search_term,
		Record<string, any>
	>
	{
		if (_caldav_resource_store === null) {
			_caldav_resource_store = lib_plankton.storage.sql_table_autokey_store(
				{
					"database_implementation": _zeitbild.database.get_implementation(),
					"table_name": "caldav_resources",
					"key_name": "id",
				}
			);
		}
		else {
			// do nothing
		}	
		return _caldav_resource_store;
	}
	
	
	/**
	 */
	function get_resource_core_store(
	) : lib_plankton.storage.type_store<
		_zeitbild.type.resource_id,
		Record<string, any>,
		{},
		lib_plankton.storage.type_sql_table_autokey_search_term,
		Record<string, any>
	>
	{
		if (_resource_core_store === null) {
			_resource_core_store = lib_plankton.storage.sql_table_autokey_store(
				{
					"database_implementation": _zeitbild.database.get_implementation(),
					"table_name": "resources",
					"key_name": "id",
				}
			);
		}
		else {
			// do nothing
		}	
		return _resource_core_store;
	}
	
	
	/**
	 */
	/*
	function encode_resource_core(
		stuff : {
			object : _zeitbild.type.resource_object;
			sub_id : int;
		}
	) : Record<string, any>
	{
		return {
			"kind": stuff.object.kind,
			"sub_id": stuff.sub_id
		};
	}
	 */
	
	
	/**
	 * @todo data
	 */
	/*
	function decode_resource_core(
		row : Record<string, any>
	) : {
		object : _zeitbild.type.resource_object;
		sub_id : int;
	}
	{
		return {
			"object": {
				"kind": row["kind"],
				"data": null,
			},
			"sub_id": row["sub_id"],
		};
	}
	 */
	
	
	/**
	 */
	function decode_event(
		row : Record<string, any>
	) : _zeitbild.type.event_object
	{
		const decode_datetime : ((datetime_raw : string) => _zeitbild.helpers.type_datetime) = ((datetime_raw) => {
			const parts : Array<string> = datetime_raw.split("|");
			const timezone_shift : int = parseInt(parts[0]);
			if (parts[1].length <= 10) {
				return {
					"timezone_shift": timezone_shift,
					"date": {
						"year": parseInt(parts[1].slice(0, 4)),
						"month": parseInt(parts[1].slice(5, 7)),
						"day": parseInt(parts[1].slice(8, 10)),
					},
					"time": null
				};
			}
			else {
				return {
					"timezone_shift": timezone_shift,
					"date": {
						"year": parseInt(parts[1].slice(0, 4)),
						"month": parseInt(parts[1].slice(5, 7)),
						"day": parseInt(parts[1].slice(8, 10)),
					},
					"time": {
						"hour": parseInt(parts[1].slice(11, 13)),
						"minute": parseInt(parts[1].slice(14, 16)),
						"second": parseInt(parts[1].slice(17, 19)),
					}
				};
			}
		});
		return {
			"name": row["name"],
			"begin": decode_datetime(row["begin"]),
			"end": (
				(row["end"] === null)
				?
				null
				:
				decode_datetime(row["end"])
			),
			"location": row["location"],
			"description": row["description"],
		};
	}
	
	
	/**
	 */
	export async function read(
		resource_id : _zeitbild.type.resource_id
	) : Promise<_zeitbild.type.resource_object>
	{
		const dataset_core : Record<string, any> = await get_resource_core_store().read(resource_id);
		switch (dataset_core.kind) {
			case "local": {
				const dataset_extra_local_core : Record<string, any> = await get_local_resource_core_store().read(dataset_core.sub_id);
				const datasets_extra_local_events : Array<Record<string, any>> = await get_local_resource_event_store().search(
					{
						"expression": "(local_resource_id = $local_resource_id)",
						"arguments": {
							"local_resource_id": dataset_core.sub_id,
						}
					}
				);
				return Promise.resolve<_zeitbild.type.resource_object>(
					{
						"kind": "local",
						"data": {
							"events": datasets_extra_local_events.map(x => decode_event(x.preview)),
						}
					}
				);
			}
			case "caldav": {
				const dataset_extra_caldav : Record<string, any> = await get_caldav_resource_store().read(dataset_core.sub_id);
				return Promise.resolve<_zeitbild.type.resource_object>(
					{
						"kind": "caldav",
						"data": {
							"url": dataset_extra_caldav["url"],
							"read_only": dataset_extra_caldav["read_only"],
						}
					}
				);
				break;
			}
			default: {
				return Promise.reject<_zeitbild.type.resource_object>(
					new Error("invalid resource kind: " + dataset_core.kind)
				);
				break;
			}
		}
	}
	
}
