<?php 
set_time_limit(180);
echo 'TEST'; 

$dontTest=array(
		
	'file','dropimagefile','dropimagethumb', //because they barf the file into the output
	'dropimage', //because it takes forever
	'userconfig', //because it doesn't return in the usual format
);

//define class autoloader
spl_autoload_register(function($className){
	$paths=array(
			'classes/',
			'classes/core/',
			'classes/core/exception/',
			'classes/core/authentication/',
			'classes/core/interface/',
			'classes/model/',
	);
	foreach($paths as $path){
		if(file_exists($path.$className.'.class.php')){
			include_once($path.$className.'.class.php');
		}
	}
});

//connect to the database
database::connect();
database::begin();

$exceptions=0;

session::init(new DummySession());
session::set('userId', 1);

tryAll();

database::abort();


function tryAll(): void {
	global $exceptions;
	
	$classDirectories=array(
		'classes/core',
		'classes/model'
	);
	
	foreach($classDirectories as $dir){
		echo '<h2>Trying classes in '.$dir.'</h2>';
		$files=scandir($dir);
		foreach($files as $f){
			if(false===stripos($f,'.class.php')){ continue; }
			echo '<b>'.$f.'</b><br/>';
			$className=substr($f,0,-10);

			echo '<i>As non-admin</i>';
			session::set('isAdmin', false);
			tryClass($className);			
			echo '<br/><i>As admin</i>';
			session::set('isAdmin', true);
			tryClass($className);
			session::set('isAdmin', false);
				
			echo '<br/><br/>';
		}
	
	}
	
}


function tryClass(string $className): void {
	
	global $dontTest;
	if(in_array($className, $dontTest)){
		echo '<br/>Not testing - class is in "Do not test" list';
		return;
	}
	
	$pagination=array(
			'pagesize'=>3,
			'pagenumber'=>1
	);
	
	try {
	
		if(!method_exists($className, 'getAll')){
				
			echo '<br/>no getAll method, not testing';
				
		} else {
	
			echo '<br/>getAll';
			$args=array($pagination);
			$result=forward_static_call_array(array($className, 'getAll'), $args);
			echo ' OK';
				
			if(empty($result)){
	
				echo '<br/>Not calling getById, no result from getAll';
				echo '<br/>Not calling getByName, no result from getAll';
	
			} else {
	
				$first=$result['rows'][0];
	
				echo '<br/>getById';
				if(!isset($first['id'])){
					echo ' - No id field, not calling getById()';
				} else {
					forward_static_call_array(array($className, 'getById'), array($first['id']));
					echo ' OK';
				}
	
				echo '<br/>getByName';
				if(!isset($first['name'])){
					echo ' - No name field, not calling getByName()';
				} else {
					forward_static_call_array(array($className, 'getByName'), array($first['name']));
					echo ' OK';
				}
	
			}
		}
			
	} catch(Exception $e){
		echo ' <span style="color:red"> threw '.get_class($e).': '.$e->getMessage().'</span>';
	}
	
}

/**
 * Present in /api/index.php, needed for some classes.
 * Calls a class method with the supplied arguments, throwing a BadRequestException if class or method does not exist.
 * @param string $className The class name
 * @param string $methodName The method name
 * @param array $args The arguments to pass to the method
 * @return mixed The results of the method call
 *@throws BadRequestException if the class or method does not exist
 */
function callOrThrow(string $className, string $methodName, array $args): mixed {
    if(!class_exists($className)){
        throw new BadRequestException('Class '.$className.' does not exist');
    }
    if(!method_exists($className, $methodName)){
        throw new BadRequestException('Class '.$className.': Method '.$methodName.' does not exist');
    }
    return forward_static_call_array(array($className, $methodName), $args);
}

