/* Ship the run's per-test results back to the host.
 *
 * The score in the page is one number; what a port actually needs is which of
 * the 6419 tests failed. tools/testsrv.py writes any POST /collect body to
 * tests/_results/<name>.txt, and the guest reaches the host at 10.0.2.2, so
 * NetSurf on KolibriOS reports through the same path Chrome does.
 *
 * Add ?name=foo to label the upload, ?collect=0 to skip it.
 */
(function () {
	function params() {
		var out = {};
		var q = location.search.replace(/^\?/, '');
		var parts = q ? q.split('&') : [];
		for (var i = 0; i < parts.length; i++) {
			var kv = parts[i].split('=');
			out[decodeURIComponent(kv[0])] = decodeURIComponent(kv[1] || '');
		}
		return out;
	}

	/* Put the document back the way the suite found it.
	 *
	 * supports.js probes through two elements it appends to <html> and never
	 * clears: a <style> whose text is rewritten for every @rule, descriptor
	 * and interface test, and a dummy element whose style attribute holds
	 * whatever value was tried last. Both are live -- the leftover sheet is
	 * in the cascade, and with the trimmed suite the last interface test to
	 * run happens to leave `div { color: red; }` behind, which turns every
	 * heading in the report red. Chrome does the same thing; it is the
	 * suite's own doing, not the engine's.
	 *
	 * That matters here more than on css3test.com: this report is read as a
	 * screenshot pulled out of the disk image, so a page that miscolours
	 * itself costs a round trip to work out that nothing is wrong. Clearing
	 * the text rather than removing the elements keeps a re-run (the filter
	 * dropdown) working, since every probe rewrites them anyway.
	 */
	function tidy() {
		var root = document.documentElement;
		var i, child;

		for (i = 0; i < root.children.length; i++) {
			child = root.children[i];
			/* Only the probes: a <style> or an unknown element sitting
			 * directly inside <html>, which no author writes. */
			if (child.tagName === 'STYLE') {
				child.textContent = '';
			} else if (child.tagName !== 'HEAD' && child.tagName !== 'BODY') {
				child.removeAttribute('style');
			}
		}
	}

	function send() {
		var p = params();

		/* Unconditional: the report has to be readable whether or not
		 * anything is listening for the results. */
		tidy();

		if (p.collect === '0' || !window.__results) {
			return;
		}

		var name = p.name || 'run';
		var lines = [
			'# score=' + (document.getElementById('score') || {}).textContent +
				' passed=' + (document.getElementById('passedTests') || {}).textContent +
				' total=' + (document.getElementById('totalTests') || {}).textContent +
				' features=' + (document.getElementById('total') || {}).textContent,
			'# ua=' + navigator.userAgent,
		];

		// A handful of test strings are multi-line (@rule bodies), so the
		// separators have to survive inside a field for one line to stay one
		// record.
		function esc(s) {
			return String(s).replace(/\\/g, '\\\\').replace(/\n/g, '\\n').replace(/\t/g, '\\t');
		}

		for (var i = 0; i < window.__results.length; i++) {
			var r = window.__results[i];
			lines.push(esc(r.spec) + '\t' + esc(r.group) + '\t' + esc(r.feature) + '\t' +
				   esc(r.test) + '\t' + r.success + '\t' + esc(r.prefix || ''));
		}

		var body = lines.join('\n');
		// The host may be elsewhere than the page origin (KolibriOS loads the
		// fixture from the image and the collector lives at 10.0.2.2).
		var base = p.collect || '';
		var url = base + '/collect?name=' + encodeURIComponent(name);

		try {
			var xhr = new XMLHttpRequest();
			xhr.open('POST', url, true);
			xhr.setRequestHeader('Content-Type', 'text/plain');
			xhr.send(body);
		} catch (e) {
			/* No channel home: the page still shows its score. */
		}
	}

	// csstest.js runs the suite from its own `onload` assignment; a listener
	// registered afterwards fires after it, with __results populated.
	if (document.readyState === 'complete') {
		setTimeout(send, 0);
	} else {
		window.addEventListener('load', function () {
			setTimeout(send, 0);
		});
	}
})();
