<?php
define('DS', DIRECTORY_SEPARATOR);
require_once __DIR__ . DS . '..' . DS . 'vendor' . DS . 'autoload.php';

class Compressor
{
	public static function css($content)
	{
		return CssMin::minify($content);
	}

	public static function js($content)
	{
		return JSMin::minify($content);
	}

	public static function html($html)
	{
		$illegalTags = ['script', 'link', 'textarea', 'pre'];
		$chunks = preg_split( '/(<(' . join('|', $illegalTags) . ')(?:\/|.*?\/\2)>)/ms', $html, -1,
		PREG_SPLIT_DELIM_CAPTURE);
		$buffer = '';
		foreach ($chunks as $chunk)
		{
			if (in_array($chunk, $illegalTags))
				continue;

			if (preg_match('/^<(' . join('|', $illegalTags) . ')/', $chunk))
			{
				$buffer .= $chunk;
				continue;
			}

			# remove new lines & tabs
			$chunk = preg_replace( '/[\\n\\r\\t]+/', ' ', $chunk);
			# remove extra whitespace
			$chunk = preg_replace( '/\\s{2,}/', ' ', $chunk);
			# remove inter-tag whitespace
			$chunk = preg_replace( '/>\\s</', '><', $chunk);
			# remove CSS & JS comments
			$chunk = preg_replace( '/\\/\\*.*?\\*\\//i', '', $chunk);
			$buffer .= $chunk;
		}
		return $buffer;
	}
}

class IndexBuilder
{
	public static function build()
	{
		$html = file_get_contents(__DIR__ . DS . 'index.html');
		self::includeTemplates($html);
		self::minifyScripts($html);
		self::minifyStylesheets($html);
		return $html;
	}

	private static function injectBody(&$html, $text)
	{
		$html = str_replace('</body>', $text . '</body>', $html);
	}

	private static function injectHead(&$html, $text)
	{
		$html = str_replace('</head>', $text . '</head>', $html);
	}

	private static function minifyScripts(&$html)
	{
		$scriptsToMinify = [];

		$html = preg_replace_callback(
			'/<script[^>]*src="([^"]+)"[^>]*><\/script>/',
			function($matches) use (&$scriptsToMinify)
			{
				$scriptPath = $matches[1];
				if (substr($scriptPath, 0, 2) == '//' or strpos($scriptPath, 'http') !== false)
					return $matches[0];
				$scriptsToMinify []= __DIR__ . DS . $scriptPath;
				return '';
			}, $html);

		$out = '<script type="text/javascript">';
		foreach ($scriptsToMinify as $scriptPath)
			$out .= Compressor::js(file_get_contents($scriptPath));
		$out .= '</script>';
		self::injectBody($html, $out);
	}

	private static function minifyStylesheets(&$html)
	{
		$html = preg_replace_callback(
			'/<link[^>]*href="([^"]+)"[^>]*>/',
			function($matches) use (&$stylesToMinify)
			{
				$stylePath = $matches[1];
				if (substr($stylePath, 0, 2) == '//' or strpos($stylePath, 'http') !== false)
					return $matches[0];
				if (strpos($matches[0], 'css') === false)
					return $matches[0];
				$stylesToMinify []= __DIR__ . DS . $stylePath;
				return '';
			}, $html);

		$out = '<style type="text/css">';
		foreach ($stylesToMinify as $stylePath)
			$out .= Compressor::css(file_get_contents($stylePath));
		$out .= '</style>';
		self::injectHead($html, $out);
	}

	private static function includeTemplates(&$html)
	{
		$templatesToInclude = [];
		foreach (glob(__DIR__ . DS . 'templates' . DS . '*.tpl') as $templatePath)
			$templatesToInclude []= $templatePath;

		$out = '';
		foreach ($templatesToInclude as $templatePath)
		{
			$out .= '<script type="text/template" id="' . str_replace('.tpl', '-template', basename($templatePath)) . '">';
			$out .= Compressor::html(file_get_contents($templatePath));
			$out .= '</script>';
		}
		self::injectBody($html, $out);
	}
}

$compiledPath = __DIR__ . DS . 'index-compiled.html';
$html = IndexBuilder::build();
$html = Compressor::html($html);
file_put_contents($compiledPath, $html);