<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse; 

class MinifyHtmlMiddleware
{

    public function handle(Request $request, Closure $next): Response
    {

        if (config('app.minify_html') == false) {
            return $next($request);
        }

        $response = $next($request);

        if ($this->isHtmlResponse($response)) {

            $buffer = $response->getContent();
            $minifiedBuffer = $this->teckel_minify_html_output($buffer);

            $response->setContent($minifiedBuffer);
        }

        return $response;
    }

    protected function isHtmlResponse(Response $response): bool
    {
        if (
            !$response->headers->has('Content-Type') ||
            str_contains($response->headers->get('Content-Type'), 'html') === false ||
            $response->isRedirection() ||
            $response instanceof StreamedResponse 
        ) {
            return false;
        }
        return true;
    }

    private function teckel_minify_html_output($buffer) {
    	if ( substr( ltrim( $buffer ), 0, 5) == '<?xml' ) {
    		return ( $buffer );
    	}
    	$minify_javascript = 'yes';
    	$minify_html_comments = 'yes';
    	$minify_html_utf8 = 'yes';
    	$mod = ( $minify_html_utf8 == 'yes' && mb_detect_encoding($buffer, 'UTF-8', true) ) ? '/u' : '/s';
    	$buffer = str_replace(array (chr(13) . chr(10), chr(9)), array (chr(10), ''), $buffer);
    	$buffer = str_ireplace(array ('<script', '/script>', '<pre', '/pre>', '<textarea', '/textarea>', '<style', '/style>'), array ('M1N1FY-ST4RT<script', '/script>M1N1FY-3ND', 'M1N1FY-ST4RT<pre', '/pre>M1N1FY-3ND', 'M1N1FY-ST4RT<textarea', '/textarea>M1N1FY-3ND', 'M1N1FY-ST4RT<style', '/style>M1N1FY-3ND'), $buffer);
    	$split = explode('M1N1FY-3ND', $buffer);
    	$buffer = ''; 
    	for ( $i=0; $i<count($split); $i++ ) {
    		$ii = strpos($split[$i], 'M1N1FY-ST4RT');
    		if ( $ii !== false ) {
    			$process = substr($split[$i], 0, $ii);
    			$asis = substr($split[$i], $ii + 12);
    			if ( substr($asis, 0, 7) == '<script' ) {
    				$split2 = explode(chr(10), $asis);
    				$asis = '';
    				for ( $iii = 0; $iii < count($split2); $iii ++ ) {
    					if ( $split2[$iii] ) {
    						$asis .= trim($split2[$iii]) . chr(10);
    					}
    					if ( $minify_javascript != 'no' ) {
    						$last = substr(trim($split2[$iii]), -1);
    						if ( strpos($split2[$iii], '//') !== false && ($last == ';' || $last == '>' || $last == '{' || $last == '}' || $last == ',') ) {
    							$asis .= chr(10);
    						}
    					}
    				}
    				if ( $asis ) {
    					$asis = substr($asis, 0, -1);
    				}
    				if ( $minify_html_comments != 'no' ) {
    					$asis = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $asis, 100000);
    				}
    				if ( $minify_javascript != 'no' ) {
    					$asis = str_replace(array (';' . chr(10), '>' . chr(10), '{' . chr(10), '}' . chr(10), ',' . chr(10)), array(';', '>', '{', '}', ','), $asis);
    				}
    			} else if ( substr($asis, 0, 6) == '<style' ) {
    				$asis = preg_replace(array ('/\>[^\S ]+' . $mod, '/[^\S ]+\<' . $mod, '/(\s)+' . $mod), array('>', '<', '\\1'), $asis, 100000);
    				if ( $minify_html_comments != 'no' ) {
    					$asis = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $asis, 100000);
    				}
    				$asis = str_replace(array (chr(10), ' {', '{ ', ' }', '} ', '( ', ' )', ' :', ': ', ' ;', '; ', ' ,', ', ', ';}'), array('', '{', '{', '}', '}', '(', ')', ':', ':', ';', ';', ',', ',', '}'), $asis);
    			}
    		} else {
    			$process = $split[$i];
    			$asis = '';
    		}
    		$process = preg_replace(array ('/\>[^\S ]+' . $mod, '/[^\S ]+\<' . $mod, '/(\s)+' . $mod, '/"\n>' . $mod, '/"\n' . $mod), array('>', '<', '\\1', '">', '" '), $process, 100000);
    		if ( $minify_html_comments != 'no' ) {
    			$process = preg_replace('/(?=<!--)([\s\S]*?)-->' . $mod, '', $process, 100000);
    		}
    		$buffer .= $process.$asis;
    	}
    	$buffer = str_replace(array (chr(10) . '<script', chr(10) . '<style', '*/' . chr(10), 'M1N1FY-ST4RT'), array('<script', '<style', '*/', ''), $buffer);
    	return ( $buffer );
    }
}