<commit_before><?php
namespace Helhum\ClassAliasLoader;

/*
 * This file is part of the class alias loader package.
 *
 * (c) <NAME> <<EMAIL>>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Composer\Package\PackageInterface;
use Composer\Package\RootPackageInterface;
use Composer\Util\Filesystem;

/**
 * Class ClassAliasLoader
 */
class ClassAliasGenerator
{
    /**
     * @param \Composer\Script\Event $event
     * @return bool
     * @throws \Exception
     */
    static public function generateAliasMap(\Composer\Script\Event $event)
    {
        $composer = $event->getComposer();
        $config = $composer->getConfig();

        $filesystem = new Filesystem();
        $filesystem->ensureDirectoryExists($config->get('vendor-dir'));
        $basePath = $filesystem->normalizePath(realpath(getcwd()));
        $vendorPath = $filesystem->normalizePath(realpath($config->get('vendor-dir')));
        $targetDir = $vendorPath . '/composer';
        $filesystem->ensureDirectoryExists($targetDir);

        $mainPackage = $composer->getPackage();
        $autoLoadGenerator = $composer->getAutoloadGenerator();
        $localRepo = $composer->getRepositoryManager()->getLocalRepository();
        $packageMap = $autoLoadGenerator->buildPackageMap($composer->getInstallationManager(), $mainPackage, $localRepo->getCanonicalPackages());

        $aliasToClassNameMapping = array();
        $classNameToAliasMapping = array();
        $classAliasMappingFound = false;

        foreach ($packageMap as $item) {
            list($package, $installPath) = $item;
            $aliasLoaderConfig = self::getAliasLoaderConfigFromPackage($package);
            if (!empty($aliasLoaderConfig['class-alias-maps'])) {
                if (!is_array($aliasLoaderConfig['class-alias-maps'])) {
                    throw new \Exception('"class-alias-maps" must be an array');
                }
                foreach ($aliasLoaderConfig['class-alias-maps'] as $mapFile) {
                    $mapFilePath = ($installPath ?: $basePath) . '/' . $filesystem->normalizePath($mapFile);
                    if (is_file($mapFilePath)) {
                        $packageAliasMap = require $mapFilePath;
                        if (!is_array($packageAliasMap)) {
                            throw new \Exception('"class alias maps" must return an array', 1422625075);
                        }
                        if (!empty($packageAliasMap)) {
                            $classAliasMappingFound = true;
                        }
                        foreach ($packageAliasMap as $aliasClassName => $className) {
                            $lowerCasedAliasClassName = strtolower($aliasClassName);
                            $aliasToClassNameMapping[$lowerCasedAliasClassName] = $className;
                            $classNameToAliasMapping[$className][$lowerCasedAliasClassName] = $lowerCasedAliasClassName;
                        }
                    }
                }
            }
        }

        $mainPackageAliasLoaderConfig = self::getAliasLoaderConfigFromPackage($mainPackage);
        $caseSensitiveClassLoading = $mainPackageAliasLoaderConfig['autoload-case-sensitivity'];

        if (!$classAliasMappingFound && !$caseSensitiveClassLoading) {
            return false;
        }

        $event->getIO()->write('<info>Generating class alias map file</info>');

        $exportArray = array(
                'aliasToClassNameMapping' => $aliasToClassNameMapping,
                'classNameToAliasMapping' => $classNameToAliasMapping
        );

        $fileContent = '<?php' . chr(10) . 'return ';
        $fileContent .= var_export($exportArray, true);
        $fileContent .= ';';

        file_put_contents($targetDir . '/autoload_classaliasmap.php', $fileContent);

        $suffix = null;
        if (!$config->get('autoloader-suffix') && is_readable($vendorPath . '/autoload.php')) {
            $content = file_get_contents($vendorPath . '/autoload.php');
            if (preg_match('{ComposerAutoloaderInit([^:\s]+)::}', $content, $match)) {
                $suffix = $match[1];
            }
        }

        if (!$suffix) {
            $suffix = $config->get('autoloader-suffix') ?: md5(uniqid('', true));
        }

        $prependAutoloader = $config->get('prepend-autoloader') === false ? 'false' : 'true';

        $aliasLoaderInitClassContent = <<<EOF
<?php

// autoload_alias_loader_real.php @generated by helhum/class-alias-loader

class ClassAliasLoaderInit$suffix {

	private static \$loader;

	static public function getAliasLoader(\$composerClassLoader) {
		if (null !== self::\$loader) {
			return self::\$loader;
		}

		\$classAliasLoader = new Helhum\ClassAliasLoader\ClassAliasLoader(\$composerClassLoader);

		\$classAliasMap = require __DIR__ . '/autoload_classaliasmap.php';
		\$classAliasLoader->setAliasMap(\$classAliasMap);
		\$classAliasLoader->setCaseSensitiveClassLoading($caseSensitiveClassLoading);
		\$classAliasLoader->register($prependAutoloader);

		self::\$loader = \$classAliasLoader;

		return \$classAliasLoader;

	}
}

EOF;
        file_put_contents($targetDir . '/autoload_alias_loader_real.php', $aliasLoaderInitClassContent);

        if (!$caseSensitiveClassLoading) {
            $event->getIO()->write('<info>Re-writing class map to support case insensitive class loading</info>');
            self::rewriteClassMapWithLowerCaseClassNames($targetDir);
        }

        $event->getIO()->write('<info>Insert class alias loader into main autoload.php file</info>');
        static::modifyMainAutoloadFile($vendorPath . '/autoload.php', $suffix);

        return true;
    }

    /**
     * @param PackageInterface $package
     * @return array
     */
    static protected function getAliasLoaderConfigFromPackage(PackageInterface $package)
    {
        $extraConfig = $package->getExtra();
        $aliasLoaderConfig = array(
                'class-alias-maps' => array(),
                'autoload-case-sensitivity' => true
        );
        if (isset($extraConfig['helhum/class-alias-loader']['class-alias-maps'])) {
            $aliasLoaderConfig['class-alias-maps'] = $extraConfig['helhum/class-alias-loader']['class-alias-maps'];
        }
        if (isset($extraConfig['helhum/class-alias-loader']['autoload-case-sensitivity'])) {
            $aliasLoaderConfig['autoload-case-sensitivity'] = (bool)$extraConfig['helhum/class-alias-loader']['autoload-case-sensitivity'];
        }

        return $aliasLoaderConfig;
    }
    /**
     * @param $autoloadFile
     * @param string $suffix
     */
    static protected function modifyMainAutoloadFile($autoloadFile, $suffix)
    {
        $originalAutoloadFileContent = file_get_contents($autoloadFile);
        preg_match('/return ComposerAutoloaderInit[^;]*;/', $originalAutoloadFileContent, $matches);
        $originalAutoloadFileContent = str_replace($matches[0], '', $originalAutoloadFileContent);
        $composerClassLoaderInit = str_replace(array('return ', ';'), '', $matches[0]);
        $autoloadFileContent = <<<EOF
$originalAutoloadFileContent

// autoload.php @generated by helhum/class-alias-loader

require_once __DIR__ . '/composer/autoload_alias_loader_real.php';

return ClassAliasLoaderInit$suffix::getAliasLoader($composerClassLoaderInit);

EOF;

        file_put_contents($autoloadFile, $autoloadFileContent);

    }

    /**
     * Rewrites the class map to have lowercased keys to be able to load classes with wrong casing
     * Defaults to case sensitivity (composer loader default)
     *
     * @param string $targetDir
     */
    static protected function rewriteClassMapWithLowerCaseClassNames($targetDir)
    {
        $classMapContents = file_get_contents($targetDir . '/autoload_classmap.php');
        $classMapContents = preg_replace_callback('/    \'[^\']*\' => /', function ($match) {
            return strtolower($match[0]);
        }, $classMapContents);
        file_put_contents($targetDir . '/autoload_classmap.php', $classMapContents);
    }
}<commit_msg>Fix typo in message<commit_after><?php
namespace Helhum\ClassAliasLoader;

/*
 * This file is part of the class alias loader package.
 *
 * (c) <NAME> <<EMAIL>>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Composer\Package\PackageInterface;
use Composer\Package\RootPackageInterface;
use Composer\Util\Filesystem;

/**
 * Class ClassAliasLoader
 */
class ClassAliasGenerator
{
    /**
     * @param \Composer\Script\Event $event
     * @return bool
     * @throws \Exception
     */
    static public function generateAliasMap(\Composer\Script\Event $event)
    {
        $composer = $event->getComposer();
        $config = $composer->getConfig();

        $filesystem = new Filesystem();
        $filesystem->ensureDirectoryExists($config->get('vendor-dir'));
        $basePath = $filesystem->normalizePath(realpath(getcwd()));
        $vendorPath = $filesystem->normalizePath(realpath($config->get('vendor-dir')));
        $targetDir = $vendorPath . '/composer';
        $filesystem->ensureDirectoryExists($targetDir);

        $mainPackage = $composer->getPackage();
        $autoLoadGenerator = $composer->getAutoloadGenerator();
        $localRepo = $composer->getRepositoryManager()->getLocalRepository();
        $packageMap = $autoLoadGenerator->buildPackageMap($composer->getInstallationManager(), $mainPackage, $localRepo->getCanonicalPackages());

        $aliasToClassNameMapping = array();
        $classNameToAliasMapping = array();
        $classAliasMappingFound = false;

        foreach ($packageMap as $item) {
            list($package, $installPath) = $item;
            $aliasLoaderConfig = self::getAliasLoaderConfigFromPackage($package);
            if (!empty($aliasLoaderConfig['class-alias-maps'])) {
                if (!is_array($aliasLoaderConfig['class-alias-maps'])) {
                    throw new \Exception('"class-alias-maps" must be an array');
                }
                foreach ($aliasLoaderConfig['class-alias-maps'] as $mapFile) {
                    $mapFilePath = ($installPath ?: $basePath) . '/' . $filesystem->normalizePath($mapFile);
                    if (is_file($mapFilePath)) {
                        $packageAliasMap = require $mapFilePath;
                        if (!is_array($packageAliasMap)) {
                            throw new \Exception('"class alias maps" must return an array', 1422625075);
                        }
                        if (!empty($packageAliasMap)) {
                            $classAliasMappingFound = true;
                        }
                        foreach ($packageAliasMap as $aliasClassName => $className) {
                            $lowerCasedAliasClassName = strtolower($aliasClassName);
                            $aliasToClassNameMapping[$lowerCasedAliasClassName] = $className;
                            $classNameToAliasMapping[$className][$lowerCasedAliasClassName] = $lowerCasedAliasClassName;
                        }
                    }
                }
            }
        }

        $mainPackageAliasLoaderConfig = self::getAliasLoaderConfigFromPackage($mainPackage);
        $caseSensitiveClassLoading = $mainPackageAliasLoaderConfig['autoload-case-sensitivity'];

        if (!$classAliasMappingFound && !$caseSensitiveClassLoading) {
            return false;
        }

        $event->getIO()->write('<info>Generating class alias map file</info>');

        $exportArray = array(
                'aliasToClassNameMapping' => $aliasToClassNameMapping,
                'classNameToAliasMapping' => $classNameToAliasMapping
        );

        $fileContent = '<?php' . chr(10) . 'return ';
        $fileContent .= var_export($exportArray, true);
        $fileContent .= ';';

        file_put_contents($targetDir . '/autoload_classaliasmap.php', $fileContent);

        $suffix = null;
        if (!$config->get('autoloader-suffix') && is_readable($vendorPath . '/autoload.php')) {
            $content = file_get_contents($vendorPath . '/autoload.php');
            if (preg_match('{ComposerAutoloaderInit([^:\s]+)::}', $content, $match)) {
                $suffix = $match[1];
            }
        }

        if (!$suffix) {
            $suffix = $config->get('autoloader-suffix') ?: md5(uniqid('', true));
        }

        $prependAutoloader = $config->get('prepend-autoloader') === false ? 'false' : 'true';

        $aliasLoaderInitClassContent = <<<EOF
<?php

// autoload_alias_loader_real.php @generated by helhum/class-alias-loader

class ClassAliasLoaderInit$suffix {

	private static \$loader;

	static public function getAliasLoader(\$composerClassLoader) {
		if (null !== self::\$loader) {
			return self::\$loader;
		}

		\$classAliasLoader = new Helhum\ClassAliasLoader\ClassAliasLoader(\$composerClassLoader);

		\$classAliasMap = require __DIR__ . '/autoload_classaliasmap.php';
		\$classAliasLoader->setAliasMap(\$classAliasMap);
		\$classAliasLoader->setCaseSensitiveClassLoading($caseSensitiveClassLoading);
		\$classAliasLoader->register($prependAutoloader);

		self::\$loader = \$classAliasLoader;

		return \$classAliasLoader;

	}
}

EOF;
        file_put_contents($targetDir . '/autoload_alias_loader_real.php', $aliasLoaderInitClassContent);

        if (!$caseSensitiveClassLoading) {
            $event->getIO()->write('<info>Re-writing class map to support case insensitive class loading</info>');
            self::rewriteClassMapWithLowerCaseClassNames($targetDir);
        }

        $event->getIO()->write('<info>Inserting class alias loader into main autoload.php file</info>');
        static::modifyMainAutoloadFile($vendorPath . '/autoload.php', $suffix);

        return true;
    }

    /**
     * @param PackageInterface $package
     * @return array
     */
    static protected function getAliasLoaderConfigFromPackage(PackageInterface $package)
    {
        $extraConfig = $package->getExtra();
        $aliasLoaderConfig = array(
                'class-alias-maps' => array(),
                'autoload-case-sensitivity' => true
        );
        if (isset($extraConfig['helhum/class-alias-loader']['class-alias-maps'])) {
            $aliasLoaderConfig['class-alias-maps'] = $extraConfig['helhum/class-alias-loader']['class-alias-maps'];
        }
        if (isset($extraConfig['helhum/class-alias-loader']['autoload-case-sensitivity'])) {
            $aliasLoaderConfig['autoload-case-sensitivity'] = (bool)$extraConfig['helhum/class-alias-loader']['autoload-case-sensitivity'];
        }

        return $aliasLoaderConfig;
    }
    /**
     * @param $autoloadFile
     * @param string $suffix
     */
    static protected function modifyMainAutoloadFile($autoloadFile, $suffix)
    {
        $originalAutoloadFileContent = file_get_contents($autoloadFile);
        preg_match('/return ComposerAutoloaderInit[^;]*;/', $originalAutoloadFileContent, $matches);
        $originalAutoloadFileContent = str_replace($matches[0], '', $originalAutoloadFileContent);
        $composerClassLoaderInit = str_replace(array('return ', ';'), '', $matches[0]);
        $autoloadFileContent = <<<EOF
$originalAutoloadFileContent

// autoload.php @generated by helhum/class-alias-loader

require_once __DIR__ . '/composer/autoload_alias_loader_real.php';

return ClassAliasLoaderInit$suffix::getAliasLoader($composerClassLoaderInit);

EOF;

        file_put_contents($autoloadFile, $autoloadFileContent);

    }

    /**
     * Rewrites the class map to have lowercased keys to be able to load classes with wrong casing
     * Defaults to case sensitivity (composer loader default)
     *
     * @param string $targetDir
     */
    static protected function rewriteClassMapWithLowerCaseClassNames($targetDir)
    {
        $classMapContents = file_get_contents($targetDir . '/autoload_classmap.php');
        $classMapContents = preg_replace_callback('/    \'[^\']*\' => /', function ($match) {
            return strtolower($match[0]);
        }, $classMapContents);
        file_put_contents($targetDir . '/autoload_classmap.php', $classMapContents);
    }
}
{'fraction_non_alphanumeric': 0.13231583482060436, 'fraction_numerical': 0.0020924364576281615, 'mean_word_length': 2.8488867835149216, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 91, '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': '7362434', 'n_tokens_mistral': 4588, 'n_tokens_neox': 4398, 'n_words': 761}