<?php

/**
 * Keep in sync with /test/middleware-mockserver.js
 */
function cleanCallback( $callback ) {
	return preg_replace( '/[^a-z0-9_]/i', '', $callback );
}

class MockServer {
	protected function contentType( $req ) {
		$type = $req->query['contentType'];
		header("Content-type: $type");
		echo $req->query['response'];
	}

	protected function wait( $req ) {
		$wait = (int) $req->query['wait'];
		sleep( $wait );
		if ( isset( $req->query['script'] ) ) {
			header( 'Content-type: text/javascript' );
		} else {
			header( 'Content-type: text/html' );
			echo 'ERROR <script>QUnit.assert.ok( true, "mock executed" );</script>';
		}
	}

	protected function name( $req ) {
		if ( $req->query['name'] === 'foo' ) {
			echo 'bar';
		} elseif ( $_POST['name'] === 'peter' ) {
			echo 'pan';
		} else {
			echo 'ERROR';
		}
	}

	protected function xml( $req ) {
		header( 'Content-type: text/xml' );
		if ( $req->query['cal'] !== '5-2' && $_POST['cal'] !== '5-2' ) {
			echo '<error>ERROR</error>';
			return;
		}
		echo "<math><calculation>5-2</calculation><result>3</result></math>\n";
	}

	protected function atom( $req ) {
		header( 'Content-type: atom+xml' );
		echo '<root><element /></root>';
	}

	protected function script( $req ) {
		if ( isset( $req->query['header'] ) ) {
			if ( $req->query['header'] === 'ecma' ) {
				header( 'Content-type: application/ecmascript' );
			} else {
				header( 'Content-type: text/javascript' );
			}
		} else {
			header( 'Content-type: text/html' );
		}
		echo 'QUnit.assert.ok( true, "mock executed" );';
	}

	// Used to be in test.js, but was renamed to testbar.php
	// https://github.com/jquery/jquery/commit/d89c278a33#commitcomment-23423165
	protected function testbar( $req ) {
		echo 'this.testBar = "bar";
jQuery("#ap").html("bar");
QUnit.assert.ok( true, "mock executed");';
	}

	protected function json( $req ) {
		if ( isset( $req->query['header'] ) ) {
			header( 'Content-type: application/json' );
		}

		if ( isset( $req->query['array'] ) ) {
			echo '[ {"name": "John", "age": 21}, {"name": "Peter", "age": 25 } ]';
		} else {
			echo '{ "data": {"lang": "en", "length": 25} }';
		}
	}

	protected function jsonp( $req ) {
		if ( isset( $req->query['callback'] ) ) {
			$callback = $req->query['callback'];
		} elseif ( $req->method === 'GET' ) {
			// Try REST-like path
			preg_match( '/\/([^\/?]+)\?.+$/', $req->url, $m );
			$callback = $m[1];
		} else {
			$callback = $_POST['callback'];
		}
		$json = isset( $req->query['array'] ) ?
			'[ { "name": "John", "age": 21 }, { "name": "Peter", "age": 25 } ]' :
			'{ "data": { "lang": "en", "length": 25 } }';
		echo cleanCallback( $callback ) . '(' . $json . ')';
	}

	protected function xmlOverJsonp( $req ) {
		$callback = $_REQUEST['callback'];
		$cleanCallback = cleanCallback( $callback );
		$text = json_encode( file_get_contents( __DIR__ . '/with_fries.xml' ) );
		echo "$cleanCallback($text)\n";
	}

	protected function error( $req ) {
		header( 'HTTP/1.0 400 Bad Request' );
		if ( isset( $req->query['json'] ) ) {
			header( 'Content-Type: application/json' );
			echo '{ "code": 40, "message": "Bad Request" }';
		} else {
			echo 'plain text message';
		}
	}

	protected function headers( $req ) {
		header( 'Sample-Header: Hello World' );
		header( 'Empty-Header: ' );
		header( 'Sample-Header2: Hello World 2' );
		header( 'List-Header: Item 1' );
		header( 'list-header: Item 2', FALSE );
		header( 'constructor: prototype collision (constructor)' );

		foreach ( explode( '|' , $req->query[ 'keys' ] ) as $key ) {
			// Only echo if key exists in the header
			if ( isset( $req->headers[ strtoupper( $key ) ] ) ) {
				echo "$key: " . $req->headers[ strtoupper( $key ) ] . "\n";
			}
		}

	}

	protected function echoData( $req ) {
		echo file_get_contents('php://input');
	}

	protected function echoQuery( $req ) {
		echo $_SERVER['QUERY_STRING'];
	}

	protected function echoMethod( $req ) {
		echo $req->method;
	}

	protected function echoHtml( $req ) {
		header( 'Content-type: text/html' );
		echo '<div id="method">' . $req->method . '</div>';
		echo '<div id="query">' . $_SERVER['QUERY_STRING'] . '</div>';
		echo '<div id="data">' . file_get_contents('php://input') . '</div>';
	}

	protected function etag( $req ) {
		$hash = md5( $req->query['ts'] );
		$etag = 'W/"' . $hash . '"';

		$ifNoneMatch = isset( $req->headers['IF-NONE-MATCH'] ) ? $req->headers['IF-NONE-MATCH'] : '';
		if ($ifNoneMatch === $etag) {
			header('HTTP/1.0 304 Not Modified');
			return;
		}

		header("Etag: $etag");
		echo "ETag: $etag\n";
		if ( $ifNoneMatch ) {
			echo "If-None-Match: $ifNoneMatch\n";
		}
	}

	protected function ims( $req ) {
		$ts = $req->query['ts'];

		$ims = isset( $req->headers['IF-MODIFIED-SINCE'] ) ? $req->headers['IF-MODIFIED-SINCE'] : '';
		if ($ims === $ts) {
			header('HTTP/1.0 304 Not Modified');
			return;
		}

		header("Last-Modified: $ts");
		echo "Last-Modified: $ts\n";
		if ( $ims ) {
			echo "If-Modified-Since: $ims\n";
		}
	}

	protected function status( $req ) {
		header( "HTTP/1.0 {$req->query['code']} {$req->query['text']}" );
	}

	protected function testHTML( $req ) {
		header( 'Content-type: text/html' );
		$html = file_get_contents( __DIR__ . '/test.include.html' );
		$html = str_replace( '{{baseURL}}', $req->query['baseURL'], $html );
		echo $html;
	}

	protected function cspFrame( $req ) {
		// This is CSP only for browsers with "Content-Security-Policy" header support
		// i.e. no old WebKit or old Firefox
		header( "Content-Security-Policy: default-src 'self'; report-uri ./mock.php?action=cspLog" );
		header( 'Content-type: text/html' );
		echo file_get_contents( __DIR__ . '/csp.include.html' );
	}

	protected function cspNonce( $req ) {
		// This is CSP only for browsers with "Content-Security-Policy" header support
		// i.e. no old WebKit or old Firefox
		$test = $req->query['test'] ? '-' . $req->query['test'] : '';
		header( "Content-Security-Policy: script-src 'nonce-jquery+hardcoded+nonce'; report-uri ./mock.php?action=cspLog" );
		header( 'Content-type: text/html' );
		echo file_get_contents( __DIR__ . '/csp-nonce' . $test . '.html' );
	}

	protected function cspLog( $req ) {
		file_put_contents( $this->cspFile, 'error' );
	}

	protected function cspClean( $req ) {
		file_put_contents( $this->cspFile, '' );
	}

	protected function errorWithScript( $req ) {
		header( 'HTTP/1.0 404 Not Found' );
		if ( isset( $req->query['withScriptContentType'] ) ) {
			header( 'Content-Type: application/javascript' );
		}
		if ( isset( $req->query['callback'] ) ) {
			$callback = $req->query['callback'];
			echo cleanCallback( $callback ) . '( {"status": 404, "msg": "Not Found"} )';
		} else {
			echo 'QUnit.assert.ok( false, "Mock return erroneously executed" );';
		}
	}

	public function __construct() {
		$this->cspFile = __DIR__ . '/support/csp.log';
	}

	public function respond( stdClass $req ) {
		if ( !isset( $req->query['action'] ) || !method_exists( $this, $req->query['action'] ) ) {
			header( "HTTP/1.0 400 Bad Request" );
			echo "Invalid action query.\n";
			return;
		}
		$this->{$req->query['action']}( $req );
	}
}

// Don't include PHP errors in http response
error_reporting( 0 );

// Collect headers
$headers = array();
foreach ( $_SERVER as $name => $value ) {
	if ( substr( $name, 0, 5 ) === 'HTTP_' ) {
		$name = str_replace( '_', '-', substr( $name, 5 ) );
		$headers[$name] = $value;
	} elseif ( $name === 'CONTENT_LENGTH' ) {
		$headers['CONTENT-LENGTH'] = $value;
	} elseif ( $name === 'CONTENT_TYPE' ) {
		$headers['CONTENT-TYPE'] = $value;
	}
}

$mock = new MockServer();
$req = (object) array(
	'query' => $_GET,
	'headers' => $headers,
	'method' => $_SERVER['REQUEST_METHOD'],
	'url' => $_SERVER['REQUEST_URI'],
);
$mock->respond( $req );
