var github = {
	params: {},

	setParams: function (params, required) {
		required = required || [];
		required.concat(['api_url', 'user_agent', 'api_version', 'repo_owner', 'repo_name', 'pagination_required', 'api_token']).forEach(function (field) {
			if (typeof params !== 'object' || typeof params[field] === 'undefined'
				|| params[field] === '') {
				throw 'Required parameter is not set: "' + field + '".';
			}
		});

		github.params = params;

		if (typeof github.params.api_url === 'string' && !github.params.api_url.endsWith('/')) {
			github.params.api_url += '/';
		}
	},

	apiRequest: function (url, pagination_required) {
		const next_pattern = /<([^>]+)>;\s*rel="next"/i;
		var request = new HttpRequest(),
			response,
			headers,
			final_data = {
				headers: {},
				data: []
			};

		pagination_required = (typeof pagination_required !== 'undefined') ? pagination_required : 'true';

		request.addHeader('User-Agent: ' + github.params.user_agent);
		request.addHeader('Accept: application/vnd.github+json');
		request.addHeader('X-GitHub-Api-Version: ' + github.params.api_version);
		request.addHeader('Authorization: Bearer ' + github.params.api_token);

		if (typeof github.params.http_proxy !== 'undefined' && github.params.http_proxy !== '') {
			request.setProxy(github.params.http_proxy);
			Zabbix.log(4, '[ GitHub Repo ] Using HTTP proxy: ' + github.params.http_proxy);
		}

		while (url) {
			Zabbix.log(4, '[ GitHub Repo ] Sending request: ' + url);

			response = request.get(url);

			Zabbix.log(4, '[ GitHub Repo ] Received response with status code ' + request.getStatus() + ': ' + response);

			if (request.getStatus() < 200 || request.getStatus() >= 300) {
				throw 'Request failed with status code ' + request.getStatus() + ': ' + response;
			}

			try {
				response = JSON.parse(response);
			}
			catch (error) {
				throw 'Failed to parse response received from API. Check debug log for more information.';
			}

			var parsed_data = github.parseData(response);
			final_data.data = final_data.data.concat(parsed_data);

			headers = request.getHeaders();

			url = ((headers.link || '').match(next_pattern) || [])[1];

			if (pagination_required === 'false') {
				url = '';
			}
		}

		final_data.headers = request.getHeaders();

		delete request;

		return final_data;
	},

	parseData: function (response_data) {
		if (!response_data) {
			return [];
		}

		const normalization_required = "total_count" in response_data && !("url" in response_data);
		if (!normalization_required) return response_data;

		delete response_data.incomplete_results;
		delete response_data.repository_selection;
		delete response_data.total_count;

		const namespaceKey = Object.keys(response_data)[0];
		response_data = response_data[namespaceKey];

		return response_data;
	},

	itemsCount: function (response_data) {
		const last_page_number = /<[^>]+page=(\d+)>;\s*rel="last"/i;

		if (response_data.headers.link){
			return response_data.headers.link.match(last_page_number)[1];
		}

		return response_data.data.length;
	}
}

try {
	github.setParams(JSON.parse(value));

	var issues_count,
		issues_count_result = {
			issues: {
				total: 0,
				open: 0,
				closed: 0
			},
			pr: {
				total: 0,
				open: 0,
				closed: 0
			}
		};

	issues_count = github.apiRequest(github.params.api_url + 'repos/' + github.params.repo_owner + '/' + github.params.repo_name + '/pulls?state=all&per_page=1', github.params.pagination_required);
	issues_count_result.pr.total = github.itemsCount(issues_count);

	issues_count = github.apiRequest(github.params.api_url + 'repos/' + github.params.repo_owner + '/' + github.params.repo_name + '/pulls?state=open&per_page=1', github.params.pagination_required);
	issues_count_result.pr.open = github.itemsCount(issues_count);

	issues_count_result.pr.closed = issues_count_result.pr.total - issues_count_result.pr.open;


	issues_count = github.apiRequest(github.params.api_url + 'repos/' + github.params.repo_owner + '/' + github.params.repo_name + '/issues?state=all&per_page=1', github.params.pagination_required);
	issues_count_result.issues.total = github.itemsCount(issues_count) - issues_count_result.pr.total;

	issues_count = github.apiRequest(github.params.api_url + 'repos/' + github.params.repo_owner + '/' + github.params.repo_name + '/issues?state=open&per_page=1', github.params.pagination_required);
	issues_count_result.issues.open = github.itemsCount(issues_count) - issues_count_result.pr.open;

	issues_count_result.issues.closed = issues_count_result.issues.total - issues_count_result.issues.open;

	return JSON.stringify(issues_count_result);
}
catch (error) {
	error += (String(error).endsWith('.')) ? '' : '.';
	Zabbix.log(3, '[ GitHub Repo ] ERROR: ' + error);
	return JSON.stringify({ error: error });
}