
namespace _zeitbild.auth
{
	
	/**
	 */
	let _subject : (
		null
		|
		lib_plankton.auth.type_auth<any, any, any>
	) = null;
	
	
	/**
	 */
	let _oidc_redict_uri_template_map : (
		null
		|
		lib_plankton.map.type_map<string, string>
	) = null;
	
	
	/**
	 */
	export function oidc_subject(
	)
	{
		return lib_plankton.auth.oidc.make(
			{
				"url_authorization": _zeitbild.conf.get().authentication.data.url_authorization,
				"url_token": _zeitbild.conf.get().authentication.data.url_token,
				"url_userinfo": _zeitbild.conf.get().authentication.data.url_userinfo,
				"client_id": _zeitbild.conf.get().authentication.data.client_id,
				"client_secret": _zeitbild.conf.get().authentication.data.client_secret,
				"url_redirect": (_zeitbild.conf.get().authentication.data.backend_url_base + "/session/oidc"),
				"scopes": [
					"openid",
					"profile",
					"email",
				],
				"label": _zeitbild.conf.get().authentication.data.label,
			}
		);
	}
	
	
	/**
	 */
	export function oidc_get_redirect_uri_template(
		key : string
	) : string
	{
		if (_oidc_redict_uri_template_map === null) {
			throw (new Error("apparently not initialized yet"));
		}
		else {
lib_plankton.log.info(
	"oidc_redirect_uri_templates",
	{
		"val": lib_plankton.map.dump(_oidc_redict_uri_template_map),
	}
);
			return _oidc_redict_uri_template_map.get(key);
		}
	}
	
	
	/**
	 */
	export function init(
	) : Promise<void>
	{
		switch (_zeitbild.conf.get().authentication.kind) {
			case "internal": {
				_subject = lib_plankton.auth.internal.implementation_auth(
					{
						"password_image_chest": {
							"setup": (input) => Promise.resolve<void>(undefined),
							"clear": () => Promise.reject<void>("not implemented"),
							"write": (key, item) => _zeitbild.repository.auth_internal.write(key, item),
							"delete": (key) => _zeitbild.repository.auth_internal.delete_(key),
							"read": (key) => _zeitbild.repository.auth_internal.read(key),
							"search": (term) => Promise.reject<any>("not implemented"),
						},
						"check_password": (image, input) => _zeitbild.service.auth_internal.check_raw(image, input),
					}
				);
				break;
			}
			case "oidc": {
				_oidc_redict_uri_template_map = lib_plankton.map.simplemap.implementation_map(
					lib_plankton.map.simplemap.make(
					)
				);
				// TODO
				return Promise.resolve(undefined);
				break;
			}
			default: {
				// do nothing
				break;
			}
		}
		return Promise.resolve<void>(undefined);
	}
	
	
	/**
	 */
	export function prepare(
		input : any
	) : Promise<{kind : string; data : any;}>
	{
		switch (_zeitbild.conf.get().authentication.kind) {
			case "oidc": {
				const subject : lib_plankton.auth.oidc.type_subject = oidc_subject();
				if (_oidc_redict_uri_template_map === null) {
					throw (new Error("apparently not initialized yet"));
				}
				else {
					_oidc_redict_uri_template_map.set(
						"foo", // TODO proper key
						input["oidc_redirect_uri_template"]
					);
					return Promise.resolve(
						{
							"kind": "oidc",
							"data": {
								"url": lib_plankton.auth.oidc.authorization_url(subject),
								"label": subject.parameters.label,
							}
						}
					);
				}
				break;
			}
			default: {
				if (_subject === null) {
					return Promise.reject(new Error("not initialized yet"));
				}
				else {
					return (
						_subject.login_prepare()
						.then(
							(data : any) => ({
								"kind": _zeitbild.conf.get().authentication.kind,
								"data": data,
							})
						)
					);
				}
				break;
			}
		}
	}
	
	
	/**
	 */
	export function execute(
		input : any
	) : Promise<string>
	{
		if (_subject === null) {
			return Promise.reject(new Error("not initialized yet"));
		}
		else {
			return _subject.login_execute(input);
		}
	}
	
	
	/**
	 */
	export function control(
		input : any
	) : Promise<void>
	{
		if (_subject === null) {
			return Promise.reject(new Error("not initialized yet"));
		}
		else {
			return _subject.login_control(input);
		}
	}
	
}
