/*------------------------------------------------------------------------
  ------------------------ OnTheAirVideo REST API ------------------------
  ------------------------------------------------------------------------*/
function RequestHandler(baseURL, authLevel) {
	this.token = undefined;
	this.serverURL = baseURL;
	this.authLevel = authLevel;
	this.onError = undefined;
	this.onFailure = undefined;

	// BASE
	this.asyncRequest = async function (path, method, queryParams, body, contentType) {
		let p = new Promise(resolve => {
			if (path != undefined && method != undefined) {
				let fullPath = this.serverURL + path;
				const self = this;
				const authRequest = path == "/authorize";

				if (queryParams === undefined) {
					queryParams = {};
				}
				if (this.token !== undefined) {
					queryParams["token"] = this.token;
				}

				let queryString = new URLSearchParams(queryParams).toString();
				if (queryString !== undefined && queryString !== "") {
					fullPath += "?" + queryString;
				}

				//JSON by default
				if (contentType === undefined) {
					contentType = 'application/json'
				}

				$.ajax({
					type: method,
					url:  fullPath,
					data: JSON.stringify(body),
					dataType: 'json',
					contentType: contentType,
					headers: {
						"Custom-Authenticate": "Yes"
					},
					success: function(response) {
						resolve(response);
					},
					error:function(response) {
						if (!authRequest) {
							if (self.onError !== undefined) {
								self.onError(response);
							}
						}

						resolve(response);
					},
					fail: function(response) {
						if (self.onFailure !== undefined) {
							self.onFailure(response);
						}

						resolve(response);
					}
				});
			} else {
				resolve(undefined);
			}
		});

		return await p;
	}

	this.asyncRequestXML = async function (path, method, queryParams, body) {
		let p = new Promise(resolve => {
			resolve(this.asyncRequest(path, method, queryParams, body, 'application/xml'));
		});

		return await p;
	}

	this.asyncAuthorize = async function(username, password) {
		let p = new Promise(resolve => {
			let body = {};
			let self = this;	//reference ourselves
			if (username && password) {
				body = {
					"username": username,
					"password": password
				};
			}
			this.asyncRequest("/authorize", "PUT", undefined, body, 'application/json').then(response => {
				if (response) {
					self.token = response.token;
					self.authLevel = response.level;
				}
				resolve(response);
			}).catch(error => {
				resolve(undefined);
			});
		})

		return await p;
	}

	// GET
	this.asyncGETActionNameValidation = async function (actionName) {
		let p = new Promise(resolve => {
			const path = "/actions/" + actionName;
			resolve(this.asyncRequest(path, "GET", queryParams));
		});

		return await p;
	}

	/*
		Returns list of OTAV available action templates
	*/
	this.asyncGETActions = async function() {
		let p = new Promise(resolve => {
			const path = "/actions";
			resolve(this.asyncRequest(path, "GET"));
		});

		return await p;
	}

	/*
		Returns list of OTAV available transitions
	*/
	this.asyncGETTransitions = async function () {
		let p = new Promise(resolve => {
			const path = "/playback/transitions";
			resolve(this.asyncRequest(path, "GET"));
		});

		return await p;
	}

	/*
		Returns playlist sepcified by ID (can also returns its items if 'include_items' param is passed)
	*/
	this.asyncGETPlaylist = async function(playlistID, queryParams) {
		let unique_id = playlistID;
		if (unique_id == "undefined" || unique_id == undefined) {
			unique_id = 0;
		}
		if(unique_id && typeof(unique_id) == "string" && unique_id.includes("/")){
			//from scheduler
			return this.asyncGETSchedulerPlaylistWithPath(unique_id);
		}

		let p = new Promise(resolve => {
			const path =  "/playlists/" + encodeURIComponent(unique_id);
			resolve(this.asyncRequest(path, "GET", queryParams));
		});

		return await p;
	}

	/*
		Returns playlist'items sepcified by playlist's ID
	*/
	this.asyncGETPlaylistItems = async function(playlistID, actionFilter) {
		let path = "/playlists/" + encodeURIComponent(playlistID) + "/items";
		let queryParams = undefined;

		if (actionFilter != undefined) {
			queryParams["filter_action_name"] = actionFilter;
		}

		let p = new Promise(resolve => {
			resolve(this.asyncRequest(path, "GET", queryParams));
		});

		return await p;
	}

	/*
		Returns playlist item sepcified by ID from a playlist
	*/
	this.asyncGETPlaylistItem = async function (playlistID, itemUniqueID, actionFilter) {
		let p = new Promise(resolve => {
			if (itemUniqueID != undefined) {
				let path = "/playlists/" + encodeURIComponent(playlistID) + "/items/" + itemUniqueID;
				let queryParams = undefined;
				if (actionFilter != undefined) {
					queryParams["filter_action_name"] = actionFilter;
				}
				resolve(this.asyncRequest(path, "GET", queryParams));
			} else {
				resolve(undefined);
			}
		});

		return await p;
	}

	/*
		Returns playlists open in OTAV instance
	*/
	this.asyncGETOpenPlaylists = async function () {
		let p = new Promise(resolve => {
			const path =  "/playlists";
			resolve(this.asyncRequest(path, "GET"));
		});

		return await p;
	}

	/*
		Returns scheduled playlists in OTAV instance's loaded schedule
	*/
	this.asyncGETSchedulerPlaylists = async function () {
		let p = new Promise(resolve => {
			const path = "/scheduler/playlists";
			resolve(this.asyncRequest(path, "GET"));
		});

		return await p;
	}

	this.asyncGETSchedulerPlaylistWithPath = async function (playlistPath) {
		let p = new Promise(resolve => {
			const path = "/scheduler/playlists";
			let queryParams = {
				"path": playlistPath
			}
			resolve(this.asyncRequest(path, "GET", queryParams));
		});

		return await p;
	}

	//PUT
	this.asyncPUTPlaylistItem = async function (playlistID, itemUniqueID, body) {
		let p = new Promise(resolve => {
			if (itemUniqueID != undefined && typeof(body) == "object") {
				const path = "/playlists/" + encodeURIComponent(playlistID) + "/items/" + itemUniqueID;
				resolve(this.asyncRequest(path, "PUT", undefined, body));
			} else {
				resolve(undefined);
			}
		});

		return await p;
	}

	this.asyncPUTPlaylistItemXML = async function (playlistID, itemUniqueID, body, queryString) {
		let p = new Promise(resolve => {
			if (itemUniqueID != undefined && typeof(body) == "string") {
				let path = "/playlists/" + encodeURIComponent(playlistID) + "/items/" + itemUniqueID;
				if (queryString != undefined) {
					path += "?" + queryString;
				}
				resolve(this.asyncRequestXML(path, "PUT", undefined, body));
			} else {
				resolve(undefined);
			}
		});

		return await p;
	}

	this.asyncPUTPlaylistItemAction = async function (playlistID, itemUniqueID, actionUniqueID, body) {
		let p = new Promise(resolve => {
			if (itemUniqueID != undefined && actionUniqueID != undefined && typeof(body) == "object") {
				const path = "/playlists/" + encodeURIComponent(playlistID) + "/items/" + itemUniqueID + "/actions/" + actionUniqueID;
				resolve(this.asyncRequest(path, "PUT", undefined, body));
			} else {
				resolve(undefined);
			}
		});

		return await p;
	}

	//POST
	this.asyncPOSTPlaylistItemAction = async function (playlistID, itemUniqueID, body) {
		let p = new Promise(resolve => {
			if (itemUniqueID != undefined && typeof(body) == "object") {
				const path = "/playlists/" + encodeURIComponent(playlistID) + "/items/" +itemUniqueID + "/actions/";
				resolve(this.asyncRequest(path, "POST", undefined, body));
			} else {
				resolve(undefined);
			}
		});

		return await p;
	}

	//DELETE
	this.asyncDELETEPlaylistItemAction = async function (playlistID, itemUniqueID, actionUniqueID) {
		let p = new Promise(resolve => {
			if (itemUniqueID != undefined && actionUniqueID != undefined) {
				const path = "/playlists/" + encodeURIComponent(playlistID) + "/items/" + itemUniqueID + "/actions/" + actionUniqueID;
				resolve(this.asyncRequest(path, "DELETE"));
			} else {
				resolve(undefined);
			}
		});

		return await p;
	}
}

/*------------------------------------------------------------------------
  ------------------------- END OF OnTheAirVideo REST API ----------------
  ------------------------------------------------------------------------*/
