<?php declare(strict_types=1);

namespace Aviat\Kilo\Tests\Tokens;

use Aviat\Kilo\Tokens\PHP8;
use PHPUnit\Framework\TestCase;

class PHP8Test extends TestCase {
	public function testGetFileTokens(): void
	{
		$filename = realpath(__DIR__ . '/../../test.php');
		$file = file_get_contents($filename);
		$tokens = PHP8::getFileTokens($filename);

		$lines = explode("\n", $file);
		array_unshift($lines, '');

		$this->verifyTokens($tokens, $lines);
	}

	public function testGetFileTokensEmptyFile(): void
	{
		$filename = __DIR__ . '/../../foobarbaz.php';
		$this->assertEmpty(PHP8::getFileTokens($filename));
	}

	private function verifyTokens(array $tokens, array $lines): void
	{
		$misplacedTokens = [];

		foreach ($tokens as $index => $lineTokens)
		{
			if (empty($lineTokens))
			{
				$this->assertEmpty(trim($lines[$index]), 'Token is empty for non-empty line');
			}

			foreach ($lineTokens as $token)
			{
				// don't compare whitespace-only tokens
				if (empty(trim($token['char'])))
				{
					continue;
				}

				$this->assertIsArray($token, 'All outputted tokens should be arrays');

				// Make sure the matched string for the token is on the correct line
				if ( ! str_contains($lines[$index], trim($token['char'])))
				{
					$token['misplaced_line'] = $index;
					$misplacedTokens[] = $token;
				}
			}
		}

		$this->assertEmpty($misplacedTokens, 'Not all tokens are on the correct lines: ' . print_r($misplacedTokens, TRUE));
	}
}