import lbry from './lbry.js';
import jsonrpc from './jsonrpc.js';

const queryTimeout = 3000;
const maxQueryTries = 2;
const defaultServers = [
	'http://lighthouse7.lbry.io:50005',
	'http://lighthouse8.lbry.io:50005',
	'http://lighthouse9.lbry.io:50005'
];
const path = '/';

let server = null;
let connectTryNum = 0;

function getServers() {
	return lbry.getClientSetting('useCustomLighthouseServers')
		? lbry.getClientSetting('customLighthouseServers')
		: defaultServers;
}

function call(method, params, callback, errorCallback) {
	if (connectTryNum >= maxQueryTries) {
		errorCallback(
			new Error(
				__(
					`Could not connect to Lighthouse server. Last server attempted: %s`,
					server
				)
			)
		);
		return;
	}

	/**
   * Set the Lighthouse server if it hasn't been set yet, if the current server is not in current
   * set of servers (most likely because of a settings change), or we're re-trying after a failed
   * query.
   */
	if (!server || !getServers().includes(server) || connectTryNum > 0) {
		// If there's a current server, filter it out so we get a new one
		const newServerChoices = server
			? getServers().filter(s => s != server)
			: getServers();
		server =
			newServerChoices[
				Math.round(Math.random() * (newServerChoices.length - 1))
			];
	}

	jsonrpc.call(
		server + path,
		method,
		params,
		response => {
			connectTryNum = 0;
			callback(response);
		},
		error => {
			connectTryNum = 0;
			errorCallback(error);
		},
		() => {
			connectTryNum++;
			call(method, params, callback, errorCallback);
		},
		queryTimeout
	);
}

const lighthouse = new Proxy(
	{},
	{
		get: function(target, name) {
			return function(...params) {
				return new Promise((resolve, reject) => {
					call(name, params, resolve, reject);
				});
			};
		}
	}
);

export default lighthouse;