/*
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.database
{
	
	/**
	 */
	const _compatible_revisions : Array<string> = [
		"r6",
	];
	
		
	/**
	 */
	export function get_implementation(
	) : lib_plankton.database.type_database
	{
		switch (_zeitbild.conf.get().database.kind) {
			case "sqlite": {
				type type_parameters = {
					path : string;
				};
				const parameters : type_parameters = (_zeitbild.conf.get().database.data as type_parameters);
				return lib_plankton.database.sqlite_database(
					{
						"path": parameters.path,
					}
				);
				break;
			}
			case "postgresql": {
				type type_parameters = {
					host : string;
					port ?: int;
					username : string;
					password : string;
					schema : string;
				};
				const parameters : type_parameters = (_zeitbild.conf.get().database.data as type_parameters);
				return lib_plankton.database.postgresql_database(
					{
						"host": parameters.host,
						"port": parameters.port,
						"username": parameters.username,
						"password": parameters.password,
						"schema": parameters.schema,
					}
				);
			}
			default: {
				throw (new Error("database implementation not available: " + _zeitbild.conf.get().database.kind));
			}
		}
	}
	
	
	/**
	 */
	function get_revision(
	) : Promise<(null | string)>
	{
		return (
			get_implementation().query_select(
				{
					"source": "_meta",
					"fields": ["revision"],
				}
			)
			.then<(null | string)>(
				(rows) => Promise.resolve<(null | string)>(rows[0]["revision"])
			)
			.catch<(null | string)>(
				(reason) => {
					lib_plankton.log.warning(
						"database_get_revision_error",
						{
							"reason": String(reason),
						}
					);
					return Promise.resolve<(null | string)>(null);
				}
			)
		);
	}
	
	
	/**
	 */
	export async function check(
	) : Promise<void>
	{
		const revision : (null | string) = await get_revision();
		lib_plankton.log.info(
			"database_check",
			{
				"revision_found": revision,
				"revisions_compatible": _compatible_revisions,
			}
		);
		if (revision === null) {
			return Promise.reject<void>(new Error("database appearently missing"));
		}
		else {
			if (! _compatible_revisions.includes(revision)) {
				return Promise.reject<void>(new Error("database revision incompatible; found: " + revision + "; required: " + String(_compatible_revisions)));
			}
			else {
				return Promise.resolve<void>(undefined);
			}
		}
	}
	
}
