<?php
set_error_handler( 'customErrorHandler' );

function customErrorHandler( $errno, $errstr, $errfile, $errline, array $errcontext ) {
	// Handles @ error suppression
	if ( error_reporting === 0 ) {
		return false;
	}

	throw new Exception( $errstr, 0 );
}

function getObfuscatedEmailAddress( $email ) {
	$alwaysEncode = array( '.', ':', '@' );

	$result = '';

	// Encode string using oct and hex character codes
	for ( $i = 0; $i < strlen( $email ); $i ++ ) {
		// Encode 25% of characters including several that always should be encoded
		if ( in_array( $email[ $i ], $alwaysEncode ) || mt_rand( 1, 100 ) < 25 ) {
			if ( mt_rand( 0, 1 ) ) {
				$result .= '&#' . ord( $email[ $i ] ) . ';';
			} else {
				$result .= '&#x' . dechex( ord( $email[ $i ] ) ) . ';';
			}
		} else {
			$result .= $email[ $i ];
		}
	}

	return $result;
}

function routeFromRequest() {
	$file = isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '';

	if ( $file === '/' ) {
		return 'index.html';
	}

	preg_match( '/\/.*\.html$/im', $file, $file );

	$file = isset( $file[0] ) ? $file[0] : false;

	$file = substr( $file, 1 );

	return $file;
}

function checkPageExists( $file ) {
	$files = glob( 'assets/*.html' );
	$files = str_replace( 'assets/', '', $files );

	if ( $file == false || ! in_array( $file, $files ) ) {
		$file = '404.html';
		header( "HTTP/1.0 404 Not Found" );
	}

	sendSecurityHeaders();

	return $file;
}

function stripOutEmails( $file ) {
	$matches = [];
	preg_match_all( '/\w*@\w*\.\w*/i', $file, $matches );
	$converted = array_map( 'getObfuscatedEmailAddress', $matches[0] );

	return str_replace( $matches[0], $converted, $file );
}

function grabPageFromAssetsFixLinks( $file ) {
	$file = file_get_contents( "./assets/{$file}" );
	$src  = '/(src|href)=("|\')(?!http|mailto|tel|callto|#|\/)([^"]*)(?<!\.html)"/im';

	return preg_replace( $src, '$1="/assets/$3"', $file );
}

function sendSecurityHeaders() {
	header( 'X-Frame-Options: DENY' );
	header( 'Cache-control: no-store' );
	header( 'Pragma: no-cache' );

	header( 'Strict-Transport-Security: max-age=31536000; includeSubDomains' );
	header( 'X-Content-Type-Options: nosniff' );
	header( 'X-Permitted-Cross-Domain-Policies: master-only' );
}

function addSecurityItemsToHead( $file ) {

	// check if CSP is already in the file
	if ( strpos( $file, 'Content-Security-Policy' ) !== false ) {
		return $file;
	}

	$csp = "<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'none'; script-src 'self' maps.google.com maps.googleapis.com; connect-src 'self'; img-src 'self' maps.gstatic.com maps.google.com; style-src 'self' 'unsafe-inline' fonts.googleapis.com;font-src 'self' fonts.gstatic.com;\">";

	$file = str_replace( '</head>', "\t$csp\n</head>", $file );

	return $file;
}

echo addSecurityItemsToHead(
	stripOutEmails(
		grabPageFromAssetsFixLinks(
			checkPageExists(
				routeFromRequest()
			)
		)
	)
);