<commit_before><?php

namespace Autoload;

require_once(__DIR__."/AutoloadException.php");
require_once(__DIR__."/OtherAutoloader.php");
require_once(__DIR__."/ClassFileOperations.php");
require_once(__DIR__."/ProcessUserGroup.php");
require_once(__DIR__."/../Globals.php");

use Autoload\AutoloadException;
use Autoload\OtherAutoloader;
use Autoload\ClassFileOperations;
use Autoload\ProcessUserGroup;
use Globals;

class Autoloader {
    const dir = __DIR__."/../";
	const space = __DIR__."/Space/";
	const chit = __DIR__."/../../chit.json";
	const classmap = __DIR__."/../../classmap.json";
	const timestamp = __DIR__."/../../timestamp.autoload";
	
	private function others(){ 
		return [
//			"OAuth2" => new OtherAutoloader($this,__DIR__."/../OAuth2/Autoloader.php","OAuth2"),
//			"phpFastCache" => new OtherAutoloader($this,__DIR__."/FastCacheAutoloader.php","phpFastCache"),
		];
	}
	
	private $permissions;
	private $prefix;
	private $fast;
	static $registered = false;
	
	/*
	 * Loads the security chit.
	 */
    private function __construct($misenpile = false)
    {
		$this->fast = !!$misenpile;
		$this->permissions = file_exists(self::chit)?json_decode(file_get_contents(self::chit))
				:[
					"policy" => [],
					"spec"	 => [],
				];
		if(file_exists(self::classmap)){
			$classmap = (array)Globals::object_to_array(json_decode(file_get_contents(self::classmap)));
			Globals::getInstance()->__autoload__ = $classmap["autoload"];
			Globals::getInstance()->__pragmas__ = $classmap["pragmas"];
		}
		$this->prefix = "a";
		if(file_exists(self::timestamp)){
			$contents = file_get_contents(self::timestamp);
			$parts = explode(",",$contents);
			$timestamp = (int)$parts[0];
			$this->prefix = $parts[1];
			if(time()-(int)$timestamp > 60*60){
				$str = "abcdefghijklmnopqrstuvwxyz";
				$rot = "bcdefghijklmnopqrstuvwxyza";
				$this->prefix = strtr($this->prefix,$str,$rot);
				$this->randomize();
			}
		}
    }

	/**
	 * Looks in the chit for a given permission
	 */
	private function findGivenPermission($namespace,$class) {
		$namespace_star = $namespace."\*";
		if(isset($this->permissions->spec->$namespace_star)){
			$value = $this->permissions->spec->$namespace_star;
			if(!is_array($value))
				return [$value];
			return $value;
		}
		$fullname = $namespace.(strlen($namespace)?"\\":"").$class;
		if(isset($this->permissions->spec->$fullname)){
			$value = $this->permissions->spec->$fullname;
			if(!is_array($value))
				return [$value];
			return $value;
		}
		return [];
	}

	/**
	 * Looks in the chit policy for a given setting
	 */
	private function findGivenSetting($setting,$default = null) {
		return isset($this->permissions->policy->$setting)?$this->permissions->policy->$setting:$default;
	}

	/*
	 * Saves the current class mappings
	 */
	public function save(){
		file_put_contents(self::classmap,json_encode([
			"autoload" => Globals::getInstance()->__autoload__,
			"pragmas" => Globals::getInstance()->__pragmas__,
		]));
		if(!file_exists(self::timestamp)){
			file_put_contents(self::timestamp,time().",{$this->prefix}");
		}
	}

	public function randomize(){
		$classmap = Globals::getInstance()->__autoload__;
		$map = [];
		foreach($classmap as $namespace => $classes){
			foreach($classes as $class => $filename){
				rename($filename,$file = $this->prefix.sha1(openssl_random_pseudo_bytes(129)));
				$map[$namespace][$class] = $file;
			}
		}
		unlink(self::timestamp);
		Globals::getInstance()->__autoload__ = $map;
	}
	
	/**
     * Registers Autoload\Autoloader as an SPL autoloader.
     */
    public static function register($reset = false,$fast = false)
    {
		if(self::$registered)
			return;
		if($reset){
			file_exists(self::timestamp) && unlink(self::timestamp);
			file_exists(self::classmap) && unlink(self::classmap);
			foreach(glob(self::space."*") as $fname){
				unlink($fname);
			}	
		}
        ini_set('unserialize_callback_func', 'spl_autoload_call');
        spl_autoload_register(array($self = new self($fast), 'autoload'));
		register_shutdown_function (function()use($self){
			$self->save();
		});
		self::$registered = true;
    }
	
    /**
     * Handles autoloading of classes.
     *
     * @param string $class A class name.
     *
     * @return boolean Returns true if the class has been loaded
     */
    public function autoload($classname)
    {
		if(class_exists($classname))
			return true;
		/*
		 * Hand off to other autoloaders
		 */
		foreach($this->others() as $ns => $other){
			if (0 === strpos($classname, $ns)) {
				if($other->autoload($classname))
					return true;
			}
		}

		$namespace = strtr($classname,"\\","/");		
		$namespace = substr($namespace,0,$tmp = strrpos($namespace,'/')?:0);
		$class = substr($classname,$tmp);
		if (!file_exists($sourcefile = self::dir.$namespace."/".$class.'.php')) {
			throw new AutoloadException("Could not find source {$sourcefile}");
		}
		$objectfile = Globals::getInstance()->lookup($namespace,$class);
		if(false===$objectfile || filemtime($objectfile) < filemtime($sourcefile)){
			ClassFileOperations::load($this,$sourcefile);
			ClassFileOperations::setNoCollect($this,$this->fast);
			$structure = ClassFileOperations::getStructure($this);
			if(!array_key_exists($namespace,$structure) || !array_key_exists($class,$structure[$namespace])){
				throw new AutoloadException("{$sourcefile} does not contain $namespace".'\\'."$class");<commit_msg>Fixed strrpos temporary variable snafu.<commit_after><?php

namespace Autoload;

require_once(__DIR__."/AutoloadException.php");
require_once(__DIR__."/OtherAutoloader.php");
require_once(__DIR__."/ClassFileOperations.php");
require_once(__DIR__."/ProcessUserGroup.php");
require_once(__DIR__."/../Globals.php");

use Autoload\AutoloadException;
use Autoload\OtherAutoloader;
use Autoload\ClassFileOperations;
use Autoload\ProcessUserGroup;
use Globals;

class Autoloader {
    const dir = __DIR__."/../";
	const space = __DIR__."/Space/";
	const chit = __DIR__."/../../chit.json";
	const classmap = __DIR__."/../../classmap.json";
	const timestamp = __DIR__."/../../timestamp.autoload";
	
	private function others(){ 
		return [
//			"OAuth2" => new OtherAutoloader($this,__DIR__."/../OAuth2/Autoloader.php","OAuth2"),
//			"phpFastCache" => new OtherAutoloader($this,__DIR__."/FastCacheAutoloader.php","phpFastCache"),
		];
	}
	
	private $permissions;
	private $prefix;
	private $fast;
	static $registered = false;
	
	/*
	 * Loads the security chit.
	 */
    private function __construct($misenpile = false)
    {
		$this->fast = !!$misenpile;
		$this->permissions = file_exists(self::chit)?json_decode(file_get_contents(self::chit))
				:[
					"policy" => [],
					"spec"	 => [],
				];
		if(file_exists(self::classmap)){
			$classmap = (array)Globals::object_to_array(json_decode(file_get_contents(self::classmap)));
			Globals::getInstance()->__autoload__ = $classmap["autoload"];
			Globals::getInstance()->__pragmas__ = $classmap["pragmas"];
		}
		$this->prefix = "a";
		if(file_exists(self::timestamp)){
			$contents = file_get_contents(self::timestamp);
			$parts = explode(",",$contents);
			$timestamp = (int)$parts[0];
			$this->prefix = $parts[1];
			if(time()-(int)$timestamp > 60*60){
				$str = "abcdefghijklmnopqrstuvwxyz";
				$rot = "bcdefghijklmnopqrstuvwxyza";
				$this->prefix = strtr($this->prefix,$str,$rot);
				$this->randomize();
			}
		}
    }

	/**
	 * Looks in the chit for a given permission
	 */
	private function findGivenPermission($namespace,$class) {
		$namespace_star = $namespace."\*";
		if(isset($this->permissions->spec->$namespace_star)){
			$value = $this->permissions->spec->$namespace_star;
			if(!is_array($value))
				return [$value];
			return $value;
		}
		$fullname = $namespace.(strlen($namespace)?"\\":"").$class;
		if(isset($this->permissions->spec->$fullname)){
			$value = $this->permissions->spec->$fullname;
			if(!is_array($value))
				return [$value];
			return $value;
		}
		return [];
	}

	/**
	 * Looks in the chit policy for a given setting
	 */
	private function findGivenSetting($setting,$default = null) {
		return isset($this->permissions->policy->$setting)?$this->permissions->policy->$setting:$default;
	}

	/*
	 * Saves the current class mappings
	 */
	public function save(){
		file_put_contents(self::classmap,json_encode([
			"autoload" => Globals::getInstance()->__autoload__,
			"pragmas" => Globals::getInstance()->__pragmas__,
		]));
		if(!file_exists(self::timestamp)){
			file_put_contents(self::timestamp,time().",{$this->prefix}");
		}
	}

	public function randomize(){
		$classmap = Globals::getInstance()->__autoload__;
		$map = [];
		foreach($classmap as $namespace => $classes){
			foreach($classes as $class => $filename){
				rename($filename,$file = $this->prefix.sha1(openssl_random_pseudo_bytes(129)));
				$map[$namespace][$class] = $file;
			}
		}
		unlink(self::timestamp);
		Globals::getInstance()->__autoload__ = $map;
	}
	
	/**
     * Registers Autoload\Autoloader as an SPL autoloader.
     */
    public static function register($reset = false,$fast = false)
    {
		if(self::$registered)
			return;
		if($reset){
			file_exists(self::timestamp) && unlink(self::timestamp);
			file_exists(self::classmap) && unlink(self::classmap);
			foreach(glob(self::space."*") as $fname){
				unlink($fname);
			}	
		}
        ini_set('unserialize_callback_func', 'spl_autoload_call');
        spl_autoload_register(array($self = new self($fast), 'autoload'));
		register_shutdown_function (function()use($self){
			$self->save();
		});
		self::$registered = true;
    }
	
    /**
     * Handles autoloading of classes.
     *
     * @param string $class A class name.
     *
     * @return boolean Returns true if the class has been loaded
     */
    public function autoload($classname)
    {
		if(class_exists($classname))
			return true;
		/*
		 * Hand off to other autoloaders
		 */
		foreach($this->others() as $ns => $other){
			if (0 === strpos($classname, $ns)) {
				if($other->autoload($classname))
					return true;
			}
		}

		$namespace = strtr($classname,"\\","/");		
		$tmp = strrpos($namespace,'/');
		$namespace = substr($namespace,0,$tmp?:0);
		if($tmp){
			$class = substr($classname,$tmp+1);
		}else{
			$class = substr($classname,$tmp+1);
		}
		if (!file_exists($sourcefile = self::dir.$namespace."/".$class.'.php')) {
			throw new AutoloadException("Could not find source {$sourcefile}");
		}
		$objectfile = Globals::getInstance()->lookup($namespace,$class);
		if(false===$objectfile || filemtime($objectfile) < filemtime($sourcefile)){
			ClassFileOperations::load($this,$sourcefile);
			ClassFileOperations::setNoCollect($this,$this->fast);
			$structure = ClassFileOperations::getStructure($this);
			if(!array_key_exists($namespace,$structure) || !array_key_exists($class,$structure[$namespace])){
				throw new AutoloadException("{$sourcefile} does not contain $namespace".'\\'."$class");
{'fraction_non_alphanumeric': 0.18535154459620498, 'fraction_numerical': 0.003116692639105326, 'mean_word_length': 4.4522738630684655, 'pattern_counts': {'":': 2, '<': 7, '<?xml version=': 0, '>': 99, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2738985', 'n_tokens_mistral': 4098, 'n_tokens_neox': 3674, 'n_words': 586}