<?php

function trailingslashit( $path ) {
	return ( substr( $path, -1, 1 ) === '/' ) ? $path : $path . '/';
}

interface WP_Autoload_Handler {
	/**
	 * @return string|null
	 */
	public function get_path( $class );
}
class WP_Autoload_Prefixed implements WP_Autoload_Handler {
	protected $prefix;
	protected $path;
	public function __construct( $prefix, $path ) {
		$this->prefix = strtolower( $prefix );
		$this->path = trailingslashit( $path );
	}
	public function get_path( $class ) {
		$class = strtolower( $class );
		if ( strpos( $class, $this->prefix ) !== 0 ) {
			return null;
		}

		$filename = 'class-' . str_replace( '_', '-', $class ) . '.php';
		return $this->path . $filename;
	}
}
class WP_Autoload_PSR0 implements WP_Autoload_Handler {
	protected $prefix;
	protected $path;
	public function __construct( $prefix, $path ) {
		$this->prefix = $prefix;
		$this->path = trailingslashit( $path );
	}
	public function get_path( $class ) {
		if ( strpos( $class, $this->prefix ) !== 0 ) {
			return null;
		}

		$parts = explode( '_', substr( $class, strlen( $this->prefix ) ) );
		$filename = implode( '/', $parts ) . '.php';
		return $this->path . $filename;
	}
}
class WP_Autoload_ClassMap implements WP_Autoload_Handler {
	protected $map;
	public function __construct( $map ) {
		$this->map = $map;
	}
	public function get_path( $class ) {
		if ( ! isset( $this->map[ $class ] ) ) {
			return null;
		}

		return $this->map[ $class ];
	}
}

$wp_autoloaders = [];
function register_autoloader( WP_Autoload_Handler $handler ) {
	global $wp_autoloaders;
	$wp_autoloaders[] = $handler;
}
function file_for_class( $class ) {
	global $wp_autoloaders;
	foreach ( $wp_autoloaders as $autoloader ) {
		if ( $path = $autoloader->get_path( $class ) ) {
			return $path;
		}
	}

	return null;
}

// Legacy
register_autoloader( new WP_Autoload_ClassMap([
	'WP' => 'wp-includes/class-wp.php',
	'wpdb' => 'wp-includes/wp-db.php',
	'WP_Date_Query' => 'wp-includes/date.php',
	'WP_Locale' => 'wp-includes/locale.php',
	'WP_oEmbed' => 'wp-includes/class-oembed.php',
	'WP_Query' => 'wp-includes/query.php',
	'WP_User_Meta_Session_Tokens' => 'wp-includes/session.php',

	// Back-compat
	'WP_HTTP_Fsockopen' => 'wp-includes/class-wp-http-streams.php',

	// Old Customizer
	'WP_Customize_Control' => 'wp-includes/class-wp-customize-control.php',
	'WP_Customize_Panel' => 'wp-includes/class-wp-customize-panel.php',
	'WP_Customize_Section' => 'wp-includes/class-wp-customize-section.php',
	'WP_Customize_Setting' => 'wp-includes/class-wp-customize-setting.php',

	// Dependencies (uses dot instead of dash)
	'WP_Dependencies' => 'wp-includes/class.wp-dependencies.php',
	'_WP_Dependency' => 'wp-includes/class.wp-dependencies.php',
	'WP_Scripts' => 'wp-includes/class.wp-scripts.php',
	'WP_Styles' => 'wp-includes/class.wp-styles.php',

	// Widgets
	'WP_Widget_Factory' => 'wp-includes/class-wp-widget-factory.php',

	// Walkers
	'Walker' => 'wp-includes/class-wp-walker.php',
	'Walker_CategoryDropdown' => 'wp-includes/class-walker-category-dropdown.php',
	'Walker_PageDropdown' => 'wp-includes/class-walker-page-dropdown.php',

	// Diff
	'WP_Text_Diff_Renderer_Table' => 'wp-includes/wp-diff.php',
	'WP_Text_Diff_Renderer_inline' => 'wp-includes/wp-diff.php',
]));

// Admin-only
register_autoloader( new WP_Autoload_ClassMap([
	// List tables
	'WP_Comments_List_Table'       => 'wp-admin/includes/class-wp-comments-list-table.php',
	'WP_Links_List_Table'          => 'wp-admin/includes/class-wp-links-list-table.php',
	'WP_List_Table'                => 'wp-admin/includes/class-wp-list-table.php',
	'WP_Media_List_Table'          => 'wp-admin/includes/class-wp-media-list-table.php',
	'WP_MS_Sites_List_Table'       => 'wp-admin/includes/class-wp-ms-sites-list-table.php',
	'WP_MS_Themes_List_Table'      => 'wp-admin/includes/class-wp-ms-themes-list-table.php',
	'WP_MS_Users_List_Table'       => 'wp-admin/includes/class-wp-ms-users-list-table.php',
	'WP_Plugin_Install_List_Table' => 'wp-admin/includes/class-wp-plugin-install-list-table.php',
	'WP_Plugins_List_Table'        => 'wp-admin/includes/class-wp-plugins-list-table.php',
	'WP_Post_Comments_List_Table'  => 'wp-admin/includes/class-wp-post-comments-list-table.php',
	'WP_Posts_List_Table'          => 'wp-admin/includes/class-wp-posts-list-table.php',
	'WP_Terms_List_Table'          => 'wp-admin/includes/class-wp-terms-list-table.php',
	'WP_Theme_Install_List_Table'  => 'wp-admin/includes/class-wp-theme-install-list-table.php',
	'WP_Themes_List_Table'         => 'wp-admin/includes/class-wp-themes-list-table.php',
	'WP_Users_List_Table'          => 'wp-admin/includes/class-wp-users-list-table.php',
	'_WP_List_Table'               => 'wp-admin/includes/list-table.php',
	'_WP_List_Table_Compat'        => 'wp-admin/includes/list-table.php',

	// Skins
	'WP_Upgrader_Skin'            => 'wp-admin/includes/class-wp-upgrader-skins.php',
	'Plugin_Upgrader_Skin'        => 'wp-admin/includes/class-wp-upgrader-skins.php',
	'Bulk_Upgrader_Skin'          => 'wp-admin/includes/class-wp-upgrader-skins.php',
	'Bulk_Plugin_Upgrader_Skin'   => 'wp-admin/includes/class-wp-upgrader-skins.php',
	'Bulk_Theme_Upgrader_Skin'    => 'wp-admin/includes/class-wp-upgrader-skins.php',
	'Plugin_Installer_Skin'       => 'wp-admin/includes/class-wp-upgrader-skins.php',
	'Theme_Installer_Skin'        => 'wp-admin/includes/class-wp-upgrader-skins.php',
	'Theme_Upgrader_Skin'         => 'wp-admin/includes/class-wp-upgrader-skins.php',
	'Language_Pack_Upgrader_Skin' => 'wp-admin/includes/class-wp-upgrader-skins.php',
	'Automatic_Upgrader_Skin'     => 'wp-admin/includes/class-wp-upgrader-skins.php',

	// Upgraders
	'WP_Upgrader'            => 'wp-admin/includes/class-wp-upgrader.php',
	'Plugin_Upgrader'        => 'wp-admin/includes/class-wp-upgrader.php',
	'Theme_Upgrader'         => 'wp-admin/includes/class-wp-upgrader.php',
	'Language_Pack_Upgrader' => 'wp-admin/includes/class-wp-upgrader.php',
	'Core_Upgrader'          => 'wp-admin/includes/class-wp-upgrader.php',
	'File_Upload_Upgrader'   => 'wp-admin/includes/class-wp-upgrader.php',
	'WP_Automatic_Updater'   => 'wp-admin/includes/class-wp-upgrader.php',

	// Admin walkers
	'Walker_Category_Checklist' => 'wp-admin/includes/class-walker-category-checklist.php',
	'Walker_Nav_Menu_Checklist' => 'wp-admin/includes/class-walker-nav-menu-checklist.php',
	'Walker_Nav_Menu_Edit'      => 'wp-admin/includes/class-walker-nav-menu-edit.php',

	// Others!
	'Custom_Background'   => 'wp-admin/custom-background.php',
	'Custom_Image_Header' => 'wp-admin/custom-header.php',
	'WP_Importer'         => 'wp-admin/includes/class-wp-importer.php',
	'WP_Press_This'       => 'wp-admin/includes/class-wp-press-this.php',
	'WP_Site_Icon'        => 'wp-admin/includes/class-wp-site-icon.php',
]));


// Externals
register_autoloader( new WP_Autoload_ClassMap([
	// AtomLib
	'AtomFeed' => 'wp-includes/atomlib.php',
	'AtomEntry' => 'wp-includes/atomlib.php',
	'AtomParser' => 'wp-includes/atomlib.php',

	// FTP handling
	'ftp' => 'wp-admin/includes/class-ftp.php',
	'ftp_base' => 'wp-admin/includes/class-ftp.php',

	// IXR
	'IXR_Value' => 'wp-includes/class-IXR.php',
	'IXR_Date' => 'wp-includes/class-IXR.php',

	// Magpie
	'MagpieRSS' => 'wp-includes/rss.php',
	'RSSCache' => 'wp-includes/rss.php',

	// ID3
	'getid3_asf' => 'wp-includes/ID3/module.audio-video.asf.php',
	'getid3_flv' => 'wp-includes/ID3/module.audio-video.flv.php',
	'AMFStream' => 'wp-includes/ID3/module.audio-video.flv.php',
	'AMFReader' => 'wp-includes/ID3/module.audio-video.flv.php',
	'AVCSequenceParameterSetReader' => 'wp-includes/ID3/module.audio-video.flv.php',
	'getid3_riff' => 'wp-includes/ID3/module.audio-video.riff.php',

	// phpass
	'PasswordHash' => 'wp-includes/class-phpass.php',

	// POMO
	'Translation_Entry' => 'wp-includes/pomo/entry.php',
	'MO' => 'wp-includes/pomo/mo.php',
	'PO' => 'wp-includes/pomo/po.php',
	'POMO_Reader' => 'wp-includes/pomo/streams.php',
	'POMO_FileReader' => 'wp-includes/pomo/streams.php',
	'POMO_StringReader' => 'wp-includes/pomo/streams.php',
	'POMO_CachedFileReader' => 'wp-includes/pomo/streams.php',
	'POMO_CachedIntFileReader' => 'wp-includes/pomo/streams.php',
	'Translations' => 'wp-includes/pomo/translations.php',
	'Gettext_Translations' => 'wp-includes/pomo/translations.php',
	'NOOP_Translations' => 'wp-includes/pomo/translations.php',

	// POP3
	'POP3' => 'wp-includes/class-pop3.php',

	// Text_Diff
	'Text_Diff' => 'wp-includes/Text/Diff.php',
	'Text_MappedDiff' => 'wp-includes/Text/Diff.php',
	'Text_Diff_Op' => 'wp-includes/Text/Diff.php',
	'Text_Diff_Op_copy' => 'wp-includes/Text/Diff.php',
	'Text_Diff_Op_change' => 'wp-includes/Text/Diff.php',
	'Text_Diff_Op_delete' => 'wp-includes/Text/Diff.php',
	'Text_Diff_Op_add' => 'wp-includes/Text/Diff.php',
]));
register_autoloader( new WP_Autoload_PSR0( 'Text_Diff_', 'wp-includes/Text/Diff/' ) );

$prefixed = [
	// Subdirs of includes
	'wp_customize_' => 'wp-includes/customize/',
	'wp_rest_' => 'wp-includes/rest-api/',
	'wp_widget_' => 'wp-includes/widgets/',

	// Admin-specific
	'wp_filesystem_' => 'wp-admin/includes/',

	// Catch-all
	'wp_' => 'wp-includes/',
	'walker_' => 'wp-includes/',
];
foreach ( $prefixed as $prefix => $path ) {
	register_autoloader( new WP_Autoload_Prefixed( $prefix, $path ) );
}

$file = fopen( 'classes.csv', 'r' );

$classes = [];
while ( ( $fields = fgetcsv( $file ) ) !== false ) {
	$classes[] = [ 'file' => $fields[0], 'class' => $fields[1] ];
}
fclose( $file );

?>
<style>
html, body {
	font-family: sans-serif;
	color: #333;
}
table {
	width: 100%;
}
.match {
	/*background: rgba( 0, 255, 0, 0.08 );*/
}
.no-match {
	background: rgba( 255, 0, 0, 0.08 );
}
</style>

<table>
	<thead>
		<tr>
			<th>Class</th>
			<th>File</th>
			<th>Expected</th>
		</tr>
	</thead>
	<tbody>
		<?php foreach ( $classes as $data ): ?>
			<?php $expected = file_for_class( $data['class'] ) ?>

			<tr>

				<td><?php echo $data['class'] ?></td>
				<td><?php echo $data['file'] ?></td>
				<td class="<?php echo ( $expected === $data['file'] ? 'match' : 'no-match' ) ?>">
					<?php echo $expected ?>
				</td>

			</tr>

		<?php endforeach ?>
	</tbody>
</table>
