
class Queue {
	static queue = []; 
	static failedRequests = 0;
	static timeout = 5000;

	static getFailedRequestCount() {
		return this.failedRequests;
	}
	static offer(promise) {
		return new Promise((resolve, reject) => {
			this.queue.unshift({
				promise,
				resolve,
				reject,
			});
		});
	}
    
	static enqueue(promise) {
		return new Promise((resolve, reject) => {
			this.queue.push({
				promise,
				resolve,
				reject,
			});
			this.dequeue();
		});
	}

	static dequeue() {
		if (this.workingOnPromise) {
			return false;
		}
		const item = this.queue.shift();
		if (!item) {
			return false;
		}
		try {

			this.workingOnPromise = true;
			const timeoutId = setTimeout(() => {
			  if(this.workingOnPromise && this.failedRequests === 0) {
				this.workingOnPromise = false;
				this.dequeue();
			  } 
			}, this.timeout);
			
			item.promise()
				.then((value) => {
					this.workingOnPromise = false;
					this.failedRequests = 0;
					clearTimeout(timeoutId);
					item.resolve(value);
					this.dequeue();
				})
				.catch(err => {
					this.queue.unshift(item);
					clearTimeout(timeoutId);
					this.onCatch(err);									
				})
		} catch (err) {
			this.queue.unshift(item);
			this.onCatch(err);
		}
		return true;
	}

	static onCatch(error) {
		// subsequent failed request count, should reset on success
		this.failedRequests++;
		console.log(this.failedRequests);
		// console.log(error);
		setTimeout(() => {
		   this.workingOnPromise = false;
		   this.dequeue();	
		}, 1000);		
	}
}
