/*
This file is part of »zeitbild«.

Copyright 2025 'kcf' <fenris@folksprak.org>

»zeitbild« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»zeitbild« 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »zeitbild«. If not, see <http://www.gnu.org/licenses/>.
 */


namespace _zeitbild.repository.group
{
	
	/**
	 */
	type type_row = {
		name : string;
		label : string;
	};
	
	
	/**
	 */
	type type_preview = {
		name : string;
		label : string;
	};
	
	
	/**
	 */
	var _store : (
		null
		|
		lib_plankton.storage.type_store<
			_zeitbild.type_user_id,
			/*type_row*/Record<string, any>,
			{},
			lib_plankton.storage.type_sql_table_autokey_search_term,
			/*type_preview*/Record<string, any>
		>
	) = null;
	
	
	/**
	 */
	function get_store(
	)
	: lib_plankton.storage.type_store<
		_zeitbild.type_user_id,
		/*type_row*/Record<string, any>,
		{},
		lib_plankton.storage.type_sql_table_autokey_search_term,
		/*type_preview*/Record<string, any>
	>
	{
		if (_store === null)
		{
			_store = lib_plankton.storage.sql_table_autokey_store(
				{
					"database_implementation": _zeitbild.database.get_implementation(),
					"table_name": "groups",
					"key_name": "id",
				}
			);
		}
		else
		{
			// do nothing
		}	
		return _store;
	}
	
	
	/**
	 */
	function encode(
		group_object : _zeitbild.type_group_object
	)
	: type_row
	{
		return {
			"name": group_object.name,
			"label": group_object.label,
		};
	}
	
	
	/**
	 */
	function decode(
		row : type_row
	)
	: _zeitbild.type_group_object
	{
		return {
			"name": row.name,
			"label": row.label,
		};
	}
	
	
	/**
	 */
	export async function list(
	)
	: Promise<
		Array<
			{
				id : _zeitbild.type_group_id;
				object : _zeitbild.type_group_object;
			}
		>
	>
	{
		const hits : Array<{key : int; preview : /*type_preview*/Record<string, any>;}> = await get_store().search({"expression": "TRUE", "arguments": {}});
		return Promise.resolve(
			hits
			.map(
				(hit) => ({
					"id": hit.key,
					"object": {
						"name": hit.preview.name,
						"label": hit.preview.label,
					}
				})
			)
		);
	}
	
	
	/**
	 */
	export async function read(
		group_id : _zeitbild.type_group_id
	)
	: Promise<_zeitbild.type_group_object>
	{
		const row : type_row = ((await get_store().read(group_id)) as type_row);
		const group_object : _zeitbild.type_group_object = decode(row);
		return Promise.resolve<_zeitbild.type_group_object>(group_object);
	}
	
	
	/**
	 */
	export async function create(
		group_object : _zeitbild.type_group_object
	)
	: Promise<_zeitbild.type_group_id>
	{
		const row : type_row = encode(group_object);
		const group_id : _zeitbild.type_group_id = await get_store().create(row);
		return Promise.resolve<_zeitbild.type_group_id>(group_id);
	}
	
	
	/**
	 */
	export async function update(
		group_id : _zeitbild.type_group_id,
		group_object : _zeitbild.type_group_object
	)
	: Promise<void>
	{
		const row : type_row = encode(group_object);
		await get_store().update(group_id, row);
		return Promise.resolve<void>(undefined);
	}
	
	
	/**
	 */
	export async function identify(
		name : string
	)
	: Promise<_zeitbild.type_group_id>
	{
		const hits : Array<{key : _zeitbild.type_group_id; preview : /*type_preview*/Record<string, any>;}> = await get_store().search(
			{
				"expression": "(name = $name)",
				"arguments": {
					"name": name,
				}
			}
		);
		if (hits.length <= 0)
		{
			return Promise.reject<_zeitbild.type_group_id>(new Error("not found"));
		}
		else
		{
			return Promise.resolve<_zeitbild.type_group_id>(hits[0].key);
		}
	}
	
}
