"use strict";

/**
 * @name Session
 *
 * @description
 * Implements actions with sessions
 *
 * @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
 * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
 */
export default class session {
	/**
	 * @name Type of the program
	 */
	static type = "module";

	/**
	 * @name Buffer
	 */
	static buffer = class buffer {
		/**
		 * @name Write
		 *
		 * @description
		 * Write to the session buffer (interface)
		 *
		 * @param {string} name Name of the parameter
		 * @param {string} value Value of the parameter (it can be JSON)
		 * @param {bool} force Ignore the damper? (false)
		 *
		 * @return {bool} Did the execution complete without errors?
		 */
		static write = (name, value, force = false) => {
			core.modules.connect("damper").then(
				() => {
					// Imported the damper module

					// Execute under damper
					this.write.damper(name, value, force);
				},
				() => {
					// Not imported the damper module

					// Execute
					this.write.system(name, value, force);
				},
			);

			// Exit (success)
			return true;
		};
	};
}

core.modules.connect("damper").then(() => {
	// Imported the damper module

	Object.assign(
		session.buffer.write,
		{
			/**
			 * @name Write (damper)
			 *
			 * @description
			 * Write to the session buffer
			 *
			 * @memberof session.buffer.write
			 *
			 * @param {string} name Name of the parameter
			 * @param {string} value Value of the parameter (it can be JSON)
			 * @param {bool} force Ignore the damper? (false)
			 *
			 * @return {Promise}
			 */
			damper: core.damper(
				(...variables) => session.buffer.write.system(...variables),
				300,
				2,
			),
		},
	);
});

Object.assign(
	session.buffer.write,
	{
		/**
		 * @name Write (system)
		 *
		 * @description
		 * Write to the session buffer
		 *
		 * @memberof session.buffer.write
		 *
		 * @param {string} name Name of the parameter
		 * @param {string} value Value of the parameter (it can be JSON)
		 *
		 * @return {Promise}
		 */
		async system(
			name,
			value,
			resolve = () => {},
			reject = () => {},
		) {
			if (
				typeof name === "string" &&
				(typeof value === "string" || typeof value === "number")
			) {
				// Received and validated required arguments

				// Sending request to the server
				return await core.request(
					"/session/write",
					`${name}=${value}`,
					"PATCH",
				)
					.then(
						(json) => {
							if (json) {
								// Received a JSON-response

								if (
									json.errors !== null &&
									typeof json.errors === "object" &&
									json.errors.length > 0
								) {
									// Fail (received errors)

									// Exit (fail)
									reject(json);
								} else {
									// Success (not received errors)

									// Exit (success)
									resolve(json);
								}
							}
						},
						() => reject(),
					);
			}
		},
	},
);

// Connecting to the core
// if (!core.session) core.session = session;
