<?php
/**
 * @brief		Runs tasks
 * @author		<a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
 * @copyright	(c) Invision Power Services, Inc.
 * @license		https://www.invisioncommunity.com/legal/standards/
 * @package		Invision Community
 * @since		24 Jun 2013
 */

// To execute a specific task pass the ID (core_tasks.id - NB: This is different to the task key)
// as the second parameter to the command
// e.g: /usr/bin/php /path/to/site/applications/core/interface/task/task.php abc1234 6
// would execute task with ID 6

use IPS\Application;
use IPS\Log;
use IPS\Settings;
use IPS\Task;
use const IPS\CIC;

@header( "Cache-Control: no-cache, no-store, must-revalidate, max-age=0, s-maxage=0" );
@header( "Expires: 0" );

/* Check this is running at the command line */
if ( !isset( $_SERVER['argv'] ) )
{
	echo "Not at command line\n";
	exit;
}

/* Init Invision Community */
define('READ_WRITE_SEPARATION', FALSE);
define('REPORT_EXCEPTIONS', TRUE);


/* Check the used PHP version and compare it with the requirements */
$path = str_replace( 'interface/task/task.php', 'data/requirements.json', str_replace( '\\', '/', __FILE__ ) );

$normalizePhpVersions = fn( array $versions ) => array_map(
	fn( string $version ) => implode( '.', array_slice( explode( '.', $version ), 0, 2 ) ),
	$versions
);

$phpVersion = $normalizePhpVersions( [ PHP_VERSION ] )[0];
$requirements = json_decode( file_get_contents( $path ), TRUE );

/* Check whether we're using a supported PHP version */
$normalizedSupportedVersions = $normalizePhpVersions( $requirements['php']['supported'] );
$supported = FALSE;
foreach( $normalizedSupportedVersions as $supportedVersion )
{
	if( version_compare( $phpVersion, $supportedVersion ) === 0 )
	{
		$supported = TRUE;
		break;
	}
}

if( !$supported )
{
	@ini_set( 'display_errors', 1 );
	trigger_error( 'The task was called with an unsupported PHP version ' . PHP_VERSION . ". PHP versions " . implode( ', ', $normalizedSupportedVersions ) . " are supported.", E_USER_ERROR );
	exit;
}

require_once str_replace( 'applications/core/interface/task/task.php', 'init.php', str_replace( '\\', '/', __FILE__ ) );

if ( !CIC and $_SERVER['argv'][1] !== Settings::i()->task_cron_key )
{
	echo "Incorrect key\n";
	exit;
}

/* Execute */
try
{
	/* Ensure applications set up correctly before task is executed. Pages, for example, needs to set up spl autoloaders first */
	Application::applications();
	
	if( isset( $_SERVER['argv'][2] ) )
	{
		$task = Task::load( $_SERVER['argv'][2], ( is_numeric( $_SERVER['argv'][2] ) ) ? NULL : 'key' );

		if ( !$task )
		{
			throw new OutOfRangeException( 'NO_TASK' );
		}
		
		$task->runAndLog();
	}
	else
	{
		while( $task = Task::queued() )
		{
			$task->runAndLog();
		}
	}
}
catch (Exception $e )
{
	Log::log( $e, 'uncaught_exception' );
	
	echo "Exception:\n";
	print_r( $e );
	exit;
}

/* Exit */
exit;