#!/usr/bin/env php
<?php declare( strict_types = 1 );

include $_composer_autoload_path ?? __DIR__.'/../vendor/autoload.php';

$communityPath = getcwd();
if( !$argv[ 1 ] ?? FALSE )
{
	$communityPath = $argv[ 1 ];
}


$metadataPath = $communityPath.'/.phpstorm.meta.php';

if( !is_dir( $metadataPath ) )
{
	mkdir( $metadataPath );
}


$finder = new \Symfony\Component\Finder\Finder();
// find all files in the current directory
$files = $finder->files()
->in( $communityPath.'/api' )
->in( $communityPath.'/admin' )
->in( $communityPath.'/applications' )
->in( $communityPath.'/system' )
->name( '*.php' )
->exclude( 'hooks' )
->contains( 'class _' );

$aliasfile = $metadataPath.'/aliases.php';
file_put_contents( $aliasfile, '<?php '.PHP_EOL );

foreach( $files as $file )
{
	// this shouldn't happen with IPS files, but ....
	$namespace = '';
	if( preg_match( '#^namespace\s+(.+?);$#sm', $file->getContents(), $m ) )
	{
		$namespace = $m[ 1 ];
	}

	$classname = $file->getBasename( '.php' );
	$newClassname = $namespace.'\\'.$classname;
	$oldClassname = $namespace.'\\_'.$classname;

	$toAdd = <<<TOADD
class_alias($oldClassname::class, '$newClassname', false);
TOADD;

	file_put_contents( $aliasfile, $toAdd.PHP_EOL, FILE_APPEND );
}

echo 'generated '.$aliasfile.PHP_EOL;


require_once $communityPath.'/init.php';

$constants = '<?php';
foreach( \IPS\IPS::defaultConstants() as $c => $v )
{
	$type = gettype( $v );
	match ( $type )
	{
		'boolean' => $v = $v ? 'true' : 'false',
		'integer' => $v = (string) $v,
		'double' => $v = (string) $v,
		'string' => $v = "'{$v}'",
		'array' => $v = '[]',
		'object' => $v = '[]',
		'resource' => $v = '[]',
		'NULL' => $v = 'null',
		'unknown type' => $v = '[]',
	};

	$constants .= PHP_EOL."define( 'IPS\\$c', {$v} );".PHP_EOL;
}

file_put_contents( $metadataPath.'/constants.php', $constants );

$m = <<<"META"
<?php
namespace PHPSTORM_META {

	exitPoint(\IPS\_Output::error());
	exitPoint(\IPS\_Output::sendOutput());
	exitPoint(\IPS\_Output::json());
	exitPoint(\IPS\_Output::redirect());
	exitPoint(\IPS\_Output::showOffline());
	exitPoint(\IPS\_Output::showBanned());
}
META;

file_put_contents( $metadataPath.'/output.php', $m );


$tables = \IPS\Db::i()->getTables( \IPS\Db::i()->prefix );
$m = <<<"META"
<?php
namespace PHPSTORM_META {

registerArgumentsSet('tables',
META;

foreach( $tables as $tableName )
{
	$m .= "'$tableName',".PHP_EOL;
}

$m .= ");
 	expectedArguments(\IPS\_Db::select(), 1, argumentsSet('tables'));
	expectedArguments(\IPS\_Db::delete(), 0, argumentsSet('tables'));
	expectedArguments(\IPS\_Db::insert(), 0, argumentsSet('tables'));
	expectedArguments(\IPS\_Db::update(), 0, argumentsSet('tables'));
}";
file_put_contents( $metadataPath.'/tables.php', $m );


$words = [];
foreach( \IPS\Application::applications() as $app )
{
	if( file_exists( \IPS\ROOT_PATH."/applications/{$app->directory}/dev/lang.php" ) )
	{
		require \IPS\ROOT_PATH."/applications/{$app->directory}/dev/lang.php";
		$words = array_merge( $words, $lang );
	}
}

$l = <<<"META"
<?php
namespace PHPSTORM_META {

registerArgumentsSet('languages',
META;

foreach( $words as $tableName => $word )
{
	$l .= "'$tableName',".PHP_EOL;
}

$l .= ");
 	expectedArguments(\IPS\_Lang::addToStack(), 0, argumentsSet('languages'));
}";
file_put_contents( $metadataPath.'/lang.php', $l );