#!/usr/bin/env php
<?php

declare(strict_types=1);

if (
	!(is_file($file = __DIR__ . '/../vendor/autoload.php') && include $file) &&
	!(is_file($file = __DIR__ . '/../../../autoload.php') && include $file)
) {
	fwrite(STDERR, "Install packages using Composer.\n");
	exit(1);
}

if (function_exists('pcntl_signal')) {
	pcntl_signal(SIGINT, function (): void {
		pcntl_signal(SIGINT, SIG_DFL);
		echo "Terminated\n";
		exit(1);
	});
} elseif (function_exists('sapi_windows_set_ctrl_handler')) {
	sapi_windows_set_ctrl_handler(function () {
		echo "Terminated\n";
		exit(1);
	});
}

set_time_limit(0);


echo '
NEON linter
-----------
';

if ($argc < 2) {
	echo "Usage: neon-lint <path>\n";
	exit(1);
}

$ok = scanPath($argv[1]);
exit($ok ? 0 : 1);


function scanPath(string $path): bool
{
	echo "Scanning $path\n";

	$it = new RecursiveDirectoryIterator($path);
	$it = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::LEAVES_ONLY);
	$it = new RegexIterator($it, '~\.neon$~');

	$counter = 0;
	$success = true;
	foreach ($it as $file) {
		echo str_pad(str_repeat('.', $counter++ % 40), 40), "\x0D";
		$success = lintFile((string) $file) && $success;
	}

	echo str_pad('', 40), "\x0D";
	echo "Done.\n";
	return $success;
}


function lintFile(string $file): bool
{
	set_error_handler(function (int $severity, string $message) use ($file) {
		if ($severity === E_USER_DEPRECATED) {
			fwrite(STDERR, "[DEPRECATED] $file    $message\n");
			return null;
		}
		return false;
	});

	$s = file_get_contents($file);
	if (substr($s, 0, 3) === "\xEF\xBB\xBF") {
		fwrite(STDERR, "[WARNING]    $file    contains BOM\n");
		$contents = substr($s, 3);
	}

	try {
		Nette\Neon\Neon::decode($s);
		return true;

	} catch (Nette\Neon\Exception $e) {
		fwrite(STDERR, "[ERROR]      $file    {$e->getMessage()}\n");

	} finally {
		restore_error_handler();
	}
	return false;
}
