"use strict";

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Api = function () {
	function Api(wsUrl) {
		var _this = this;

		_classCallCheck(this, Api);

		var WebSocketClient = typeof WebSocket !== "undefined" ? require("ReconnectingWebSocket") : require("websocket").w3cwebsocket;

		try {
			this.ws = new WebSocketClient(wsUrl);
		} catch (err) {
			console.error("ws error:", err);
		}

		this.ws.timeoutInterval = 15000;

		this.connectPromise = new Promise(function (resolve, reject) {

			_this.ws.onopen = function () {
				resolve();
			};

			_this.ws.onerror = function (err) {
				reject(err);
			};

			_this.ws.onmessage = function (message) {
				_this.listener(JSON.parse(message.data));
			};
		});

		this.cbId = 0;
		this.cbs = new Map();
	}

	_createClass(Api, [{
		key: "listener",
		value: function listener(message) {
			var callback = this.cbs.get(message.id);
			if (callback) {
				if ("error" in message) {
					callback.reject(message.error);
				} else {
					callback.resolve(message.result);
				}
			}
		}
	}, {
		key: "call",
		value: function call(params) {
			var _this2 = this;

			var request = {
				method: "call",
				params: params,
				id: this.cbId++
			};

			return new Promise(function (resolve, reject) {

				_this2.cbs.set(request.id, {
					time: new Date(),
					resolve: resolve,
					reject: reject
				});

				_this2.ws.onerror = function (error) {
					reject(error);
				};

				_this2.ws.send(JSON.stringify(request));
			});
		}
	}, {
		key: "getApiByName",
		value: function getApiByName(api) {
			return this.call([1, "get_api_by_name", [api]]);
		}
	}, {
		key: "login",
		value: function login(user, password) {
			var _this3 = this;

			return this.connectPromise.then(function () {
				return _this3.call([1, "login", [user, password]]);
			});
		}
	}, {
		key: "close",
		value: function close() {
			this.ws.close();
		}
	}]);

	return Api;
}();

module.exports = Api;