/* eslint no-multi-str: "off" */

var FILEPATH = "/test/data/testinit.js",
	activeScript = [].slice.call( document.getElementsByTagName( "script" ), -1 )[ 0 ],
	parentUrl = activeScript && activeScript.src ?
		activeScript.src.replace( /[?#].*/, "" ) + FILEPATH.replace( /[^/]+/g, ".." ) + "/" :
		"../",

	// baseURL is intentionally set to "data/" instead of "".
	// This is not just for convenience (since most files are in data/)
	// but also to ensure that urls without prefix fail.
	// Otherwise it's easy to write tests that pass on test/index.html
	// but fail in Karma runner (where the baseURL is different).
	baseURL = parentUrl + "test/data/",
	supportjQuery = this.jQuery,

	// see RFC 2606
	externalHost = "example.com",

	// NOTE: keep it in sync with build/tasks/lib/slim-build-flags.js
	slimBuildFlags = [
		"-ajax",
		"-effects"
	];

this.hasPHP = true;
this.isLocal = window.location.protocol === "file:";

// Setup global variables before loading jQuery for testing .noConflict()
supportjQuery.noConflict( true );
window.originaljQuery = this.jQuery = undefined;
window.original$ = this.$ = "replaced";

/**
 * Returns an array of elements with the given IDs
 * @example q( "main", "foo", "bar" )
 * @result [<div id="main">, <span id="foo">, <input id="bar">]
 */
this.q = function() {
	var r = [],
		i = 0;

	for ( ; i < arguments.length; i++ ) {
		r.push( document.getElementById( arguments[ i ] ) );
	}
	return r;
};

/**
 * Asserts that a select matches the given IDs
 * @param {String} message - Assertion name
 * @param {String} selector - Sizzle selector
 * @param {String} expectedIds - Array of ids to construct what is expected
 * @param {(String|Node)=document} context - Selector context
 * @example match("Check for something", "p", ["foo", "bar"]);
 */
function match( message, selector, expectedIds, context, assert ) {
	var f = jQuery( selector, context ).get(),
		s = "",
		i = 0;

	for ( ; i < f.length; i++ ) {
		s += ( s && "," ) + "\"" + f[ i ].id + "\"";
	}

	assert.deepEqual( f, q.apply( q, expectedIds ), message + " (" + selector + ")" );
}

/**
 * Asserts that a select matches the given IDs.
 * The select is not bound by a context.
 * @param {String} message - Assertion name
 * @param {String} selector - Sizzle selector
 * @param {String} expectedIds - Array of ids to construct what is expected
 * @example t("Check for something", "p", ["foo", "bar"]);
 */
QUnit.assert.t = function( message, selector, expectedIds ) {
	match( message, selector, expectedIds, undefined, QUnit.assert );
};

/**
 * Asserts that a select matches the given IDs.
 * The select is performed within the `#qunit-fixture` context.
 * @param {String} message - Assertion name
 * @param {String} selector - Sizzle selector
 * @param {String} expectedIds - Array of ids to construct what is expected
 * @example selectInFixture("Check for something", "p", ["foo", "bar"]);
 */
QUnit.assert.selectInFixture = function( message, selector, expectedIds ) {
	match( message, selector, expectedIds, "#qunit-fixture", QUnit.assert );
};

this.createDashboardXML = function() {
	var string = "<?xml version='1.0' encoding='UTF-8'?> \
	<dashboard> \
		<locations class='foo'> \
			<location for='bar' checked='different'> \
				<infowindowtab normal='ab' mixedCase='yes'> \
					<tab title='Location'><![CDATA[blabla]]></tab> \
					<tab title='Users'><![CDATA[blublu]]></tab> \
				</infowindowtab> \
			</location> \
		</locations> \
	</dashboard>";

	return jQuery.parseXML( string );
};

this.createWithFriesXML = function() {
	var string = "<?xml version='1.0' encoding='UTF-8'?> \
	<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' \
		xmlns:xsd='http://www.w3.org/2001/XMLSchema' \
		xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> \
		<soap:Body> \
			<jsconf xmlns='http://{{ externalHost }}/ns1'> \
				<response xmlns:ab='http://{{ externalHost }}/ns2'> \
					<meta> \
						<component id='seite1' class='component'> \
							<properties xmlns:cd='http://{{ externalHost }}/ns3'> \
								<property name='prop1'> \
									<thing /> \
									<value>1</value> \
								</property> \
								<property name='prop2'> \
									<thing att='something' /> \
								</property> \
								<foo_bar>foo</foo_bar> \
							</properties> \
						</component> \
					</meta> \
				</response> \
			</jsconf> \
		</soap:Body> \
	</soap:Envelope>";

	return jQuery.parseXML( string.replace( /\{\{\s*externalHost\s*\}\}/g, externalHost ) );
};

this.createXMLFragment = function() {
	var xml, frag;
	if ( window.ActiveXObject ) {
		xml = new window.ActiveXObject( "msxml2.domdocument" );
	} else {
		xml = document.implementation.createDocument( "", "", null );
	}

	if ( xml ) {
		frag = xml.createElement( "data" );
	}

	return frag;
};

window.fireNative = document.createEvent ?
	function( node, type ) {
		var event = document.createEvent( "HTMLEvents" );

		event.initEvent( type, true, true );
		node.dispatchEvent( event );
	} :
	function( node, type ) {
		node.fireEvent( "on" + type, document.createEventObject() );
	};

/**
 * Add random number to url to stop caching
 *
 * Also prefixes with baseURL automatically.
 *
 * @example url("index.html")
 * @result "data/index.html?10538358428943"
 *
 * @example url("mock.php?foo=bar")
 * @result "data/mock.php?foo=bar&10538358345554"
 */
function url( value ) {
	return baseURL + value + ( /\?/.test( value ) ? "&" : "?" ) +
		new Date().getTime() + "" + parseInt( Math.random() * 100000, 10 );
}

// Ajax testing helper
this.ajaxTest = function( title, expect, options ) {
	QUnit.test( title, function( assert ) {
		assert.expect( expect );
		var requestOptions;

		if ( typeof options === "function" ) {
			options = options( assert );
		}
		options = options || [];
		requestOptions = options.requests || options.request || options;
		if ( !Array.isArray( requestOptions ) ) {
			requestOptions = [ requestOptions ];
		}

		var done = assert.async();

		if ( options.setup ) {
			options.setup();
		}

		var completed = false,
			remaining = requestOptions.length,
			complete = function() {
				if ( !completed && --remaining === 0 ) {
					completed = true;
					delete ajaxTest.abort;
					if ( options.teardown ) {
						options.teardown();
					}

					// Make sure all events will be called before done()
					setTimeout( done );
				}
			},
			requests = jQuery.map( requestOptions, function( options ) {
				var request = ( options.create || jQuery.ajax )( options ),
					callIfDefined = function( deferType, optionType ) {
						var handler = options[ deferType ] || !!options[ optionType ];
						return function( _, status ) {
							if ( !completed ) {
								if ( !handler ) {
									assert.ok( false, "unexpected " + status );
								} else if ( typeof handler === "function" ) {
									handler.apply( this, arguments );
								}
							}
						};
					};

				if ( options.afterSend ) {
					options.afterSend( request, assert );
				}

				return request
					.done( callIfDefined( "done", "success" ) )
					.fail( callIfDefined( "fail", "error" ) )
					.always( complete );
			} );

		ajaxTest.abort = function( reason ) {
			if ( !completed ) {
				completed = true;
				delete ajaxTest.abort;
				assert.ok( false, "aborted " + reason );
				jQuery.each( requests, function( i, request ) {
					request.abort();
				} );
			}
		};
	} );
};

this.testIframe = function( title, fileName, func, wrapper ) {
	if ( !wrapper ) {
		wrapper = QUnit.test;
	}
	wrapper.call( QUnit, title, function( assert ) {
		var done = assert.async(),
			$iframe = supportjQuery( "<iframe></iframe>" )
				.css( { position: "absolute", top: "0", left: "-600px", width: "500px" } )
				.attr( { id: "qunit-fixture-iframe", src: url( fileName ) } );

		// Test iframes are expected to invoke this via startIframeTest (cf. iframeTest.js)
		window.iframeCallback = function() {
			var args = Array.prototype.slice.call( arguments );

			args.unshift( assert );

			setTimeout( function() {
				var result;

				this.iframeCallback = undefined;

				result = func.apply( this, args );

				function finish() {
					func = function() {};
					$iframe.remove();
					done();
				}

				// Wait for promises returned by `func`.
				if ( result && result.then ) {
					result.then( finish );
				} else {
					finish();
				}
			} );
		};

		// Attach iframe to the body for visibility-dependent code
		// It will be removed by either the above code, or the testDone callback in testrunner.js
		$iframe.prependTo( document.body );
	} );
};
this.iframeCallback = undefined;

// Tests are always loaded async
// except when running tests in Karma (See Gruntfile)
if ( !window.__karma__ ) {
	QUnit.config.autostart = false;
}

// Leverage QUnit URL parsing to detect testSwarm environment and "basic" testing mode
QUnit.isSwarm = ( QUnit.urlParams.swarmURL + "" ).indexOf( "http" ) === 0;
QUnit.basicTests = ( QUnit.urlParams.module + "" ) === "basic";

// Async test for module script type support
function moduleTypeSupported() {
	var script = document.createElement( "script" );
	script.type = "module";
	script.text = "QUnit.moduleTypeSupported = true";
	document.head.appendChild( script ).parentNode.removeChild( script );
}
moduleTypeSupported();

// Returns whether a particular module like "ajax" or "deprecated"
// is included in the current jQuery build; it handles the slim build
// as well. The util was created so that we don't treat presence of
// particular APIs to decide whether to run a test as then if we
// accidentally remove an API, the tests would still not fail.
this.includesModule = function( moduleName ) {

	var excludedModulesPart, excludedModules;

	// A short-cut for the slim build, e.g. "4.0.0-pre slim"
	if ( jQuery.fn.jquery.indexOf( " slim" ) > -1 ) {

		// The module is included if it does NOT exist on the list
		// of modules excluded in the slim build
		return slimBuildFlags.indexOf( "-" + moduleName ) === -1;
	}

	// example version for `grunt custom:-deprecated`:
	// "4.0.0-pre -deprecated,-deprecated/ajax-event-alias,-deprecated/event"
	excludedModulesPart = jQuery.fn.jquery

		// Take the flags out of the version string.
		// Example: "-deprecated,-deprecated/ajax-event-alias,-deprecated/event"
		.split( " " )[ 1 ];

	if ( !excludedModulesPart ) {

		// No build part => the full build where everything is included.
		return true;
	}

	excludedModules = excludedModulesPart

		// Turn to an array.
		// Example: [ "-deprecated", "-deprecated/ajax-event-alias", "-deprecated/event" ]
		.split( "," )

		// Remove the leading "-".
		// Example: [ "deprecated", "deprecated/ajax-event-alias", "deprecated/event" ]
		.map( function( moduleName ) {
			return moduleName.slice( 1 );
		} )

		// Filter out deep names - ones that contain a slash.
		// Example: [ "deprecated" ]
		.filter( function( moduleName ) {
			return moduleName.indexOf( "/" ) === -1;
		} );

	return excludedModules.indexOf( moduleName ) === -1;
};

this.loadTests = function() {

	// QUnit.config is populated from QUnit.urlParams but only at the beginning
	// of the test run. We need to read both.
	var amd = QUnit.config.amd || QUnit.urlParams.amd;

	// Directly load tests that need evaluation before DOMContentLoaded.
	if ( !amd || document.readyState === "loading" ) {
		document.write( "<script src='" + parentUrl + "test/unit/ready.js'><\x2Fscript>" );
	} else {
		QUnit.module( "ready", function() {
			QUnit.skip( "jQuery ready tests skipped in async mode", function() {} );
		} );
	}

	// Get testSubproject from testrunner first
	require( [ parentUrl + "test/data/testrunner.js" ], function() {
		var i = 0,
			tests = [
				// A special module with basic tests, meant for
				// not fully supported environments like Android 2.3,
				// jsdom or PhantomJS. We run it everywhere, though,
				// to make sure tests are not broken.
				"unit/basic.js",

				"unit/core.js",
				"unit/callbacks.js",
				"unit/deferred.js",
				"unit/deprecated.js",
				"unit/support.js",
				"unit/data.js",
				"unit/queue.js",
				"unit/attributes.js",
				"unit/event.js",
				"unit/selector.js",
				"unit/traversing.js",
				"unit/manipulation.js",
				"unit/wrap.js",
				"unit/css.js",
				"unit/serialize.js",
				"unit/ajax.js",
				"unit/effects.js",
				"unit/offset.js",
				"unit/dimensions.js",
				"unit/animation.js",
				"unit/tween.js"
			];

		// Ensure load order (to preserve test numbers)
		( function loadDep() {
			var dep = tests[ i++ ];

			if ( dep ) {
				if ( !QUnit.basicTests || i === 1 ) {
					require( [ parentUrl + "test/" + dep ], loadDep );

				// Support: Android 2.3 only
				// When running basic tests, replace other modules with dummies to avoid overloading
				// impaired clients.
				} else {
					QUnit.module( dep.replace( /^.*\/|\.js$/g, "" ) );
					loadDep();
				}

			} else {
				if ( window.__karma__ && window.__karma__.start ) {
					window.__karma__.start();
				} else {
					QUnit.load();
				}

				/**
				 * Run in noConflict mode
				 */
				jQuery.noConflict();

				// Load the TestSwarm listener if swarmURL is in the address.
				if ( QUnit.isSwarm ) {
					require( [ "https://swarm.jquery.org/js/inject.js?" + ( new Date() ).getTime() ],
					function() {
						QUnit.start();
					} );
				} else {
					QUnit.start();
				}
			}
		} )();
	} );
};
