<?php
/**
 * PSR-4 style autoloader mapping WordPress file naming conventions.
 *
 * @package MenuVerse
 */

namespace WPXero\MenuVerse;

defined( 'ABSPATH' ) || exit;

/**
 * Resolves plugin class names to files without a Composer runtime dependency.
 */
final class Autoloader {

	/**
	 * Root namespace handled by this autoloader.
	 *
	 * @var string
	 */
	const NAMESPACE_PREFIX = 'WPXero\\MenuVerse\\';

	/**
	 * Namespace segment that resolves to the top level modules directory.
	 *
	 * @var string
	 */
	const MODULE_SEGMENT = 'Module';

	/**
	 * Registers the autoloader with SPL.
	 *
	 * @return void
	 */
	public static function register() {
		spl_autoload_register( array( __CLASS__, 'load' ) );
	}

	/**
	 * Attempts to load the file backing a class name.
	 *
	 * @param string $class_name Fully qualified class name.
	 * @return void
	 */
	public static function load( $class_name ) {
		if ( 0 !== strpos( $class_name, self::NAMESPACE_PREFIX ) ) {
			return;
		}

		$relative = substr( $class_name, strlen( self::NAMESPACE_PREFIX ) );
		$segments = explode( '\\', $relative );
		$entity   = array_pop( $segments );

		if ( isset( $segments[0] ) && self::MODULE_SEGMENT === $segments[0] ) {
			array_shift( $segments );
			$base = MENUVERSE_PATH . 'modules/';
		} else {
			$base = MENUVERSE_PATH . 'includes/';
		}

		foreach ( $segments as $segment ) {
			$base .= self::to_slug( $segment ) . '/';
		}

		$slug = self::to_slug( $entity );

		foreach ( array( 'class-', 'interface-', 'trait-' ) as $prefix ) {
			$file = $base . $prefix . $slug . '.php';

			if ( is_readable( $file ) ) {
				require_once $file;
				return;
			}
		}
	}

	/**
	 * Converts a namespace or class segment to its file slug.
	 *
	 * @param string $segment Namespace or class segment.
	 * @return string
	 */
	private static function to_slug( $segment ) {
		return strtolower( str_replace( '_', '-', $segment ) );
	}
}
