<?php

namespace Salesloo;

if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly.
}

/**
 * Salesloo autoloader.
 *
 * Salesloo autoloader handler class is responsible for loading the different
 * classes needed to run the plugin.
 */
class Autoloader
{

    /**
     * Classes map.
     *
     * Maps Salesloo classes to file names.
     * 
     */
    private static $classes_map;

    /**
     * Run autoloader.
     *
     * Register a function as `__autoload()` implementation.
     */
    public static function run()
    {
        spl_autoload_register([__CLASS__, 'autoload']);

        require SALESLOO_PATH . 'includes/function-core.php';
        require SALESLOO_PATH . 'includes/function-template.php';
        require SALESLOO_PATH . 'includes/function-option.php';
        require SALESLOO_PATH . 'includes/function-product.php';
        require SALESLOO_PATH . 'includes/function-affiliate.php';
        require SALESLOO_PATH . 'includes/function-coupon.php';
        require SALESLOO_PATH . 'includes/function-affiliate-click.php';
        require SALESLOO_PATH . 'includes/function-cart.php';
        require SALESLOO_PATH . 'includes/function-order.php';
        require SALESLOO_PATH . 'includes/function-user.php';
        require SALESLOO_PATH . 'includes/function-commission.php';
        require SALESLOO_PATH . 'includes/function-invoice.php';
        require SALESLOO_PATH . 'includes/function-access.php';
        require SALESLOO_PATH . 'includes/function-checkout.php';
        require SALESLOO_PATH . 'includes/function-file.php';
        require SALESLOO_PATH . 'includes/function-notification.php';
        require SALESLOO_PATH . 'includes/function-email.php';
        require SALESLOO_PATH . 'includes/function-addon.php';
        require SALESLOO_PATH . 'includes/function-webhook.php';
        require SALESLOO_PATH . 'includes/function-event.php';
        require SALESLOO_PATH . 'includes/function-upgrade.php';
        require SALESLOO_PATH . 'includes/function-tracking.php';
        require SALESLOO_PATH . 'includes/function-admin.php';
        require SALESLOO_PATH . 'includes/function-admin-fields.php';
    }

    /**
     * get classes map
     */
    public static function get_classes_map()
    {
        if (!self::$classes_map) {
            self::init_classes_map();
        }

        return self::$classes_map;
    }

    /**
     * Classes Map
     * 
     * Init classes map
     */
    private static function init_classes_map()
    {
        self::$classes_map = [
            'Builder'                                 => 'includes/builder.php',
            'Collection'                              => 'includes/collection.php',
            'Abstracts\Database'                      => 'includes/abstracts/database.php',
            'Abstracts\Setting_Page'                  => 'includes/abstracts/setting-page.php',
            'Abstracts\Frontend'                      => 'includes/abstracts/frontend.php',
            'Abstracts\Payment_Method'                => 'includes/abstracts/payment-method.php',
            'Abstracts\Rest_Api'                      => 'includes/abstracts/rest-api.php',
            'Abstracts\Notification'                  => 'includes/abstracts/notification.php',
            'Abstracts\Email'                         => 'includes/abstracts/email.php',
            'Abstracts\Fields'                        => 'includes/abstracts/fields.php',
            'Admin'                                   => 'includes/admin.php',
            'Frontend'                                => 'includes/frontend.php',
            'System_Info'                             => 'includes/system-info.php',
            'Settings'                                => 'includes/settings.php',
            'Files'                                   => 'includes/files.php',
            'Webhooks'                                => 'includes/webhooks.php',
            'Page'                                    => 'includes/page.php',
            'Products'                                => 'includes/products.php',
            'Coupon'                                  => 'includes/coupon.php',
            'Affiliate'                               => 'includes/affiliate.php',
            'Orders'                                  => 'includes/orders.php',
            'Payment'                                 => 'includes/payment.php',
            'Invoice'                                 => 'includes/invoice.php',
            'Payment_Method'                          => 'includes/payment-method.php',
            'Request'                                 => 'includes/request.php',
            'Response'                                => 'includes/response.php',
            'Rest_Api'                                => 'includes/rest-api.php',
            'Notifications'                           => 'includes/notifications.php',
            'Compatibility'                           => 'includes/compatibility.php',
            'Addon'                                   => 'includes/addon.php',
            'License'                                 => 'includes/license.php',
            'Upgrade'                                 => 'includes/upgrade.php',
            'Events'                                  => 'includes/events.php',
            'Admin_Ajax'                              => 'includes/admin-ajax.php',
            'Checkout'                                => 'includes/checkout.php',
            'Renew'                                   => 'includes/renew.php',
            'Cart'                                    => 'includes/cart.php',
            'User'                                    => 'includes/user.php',
            'Models\Product'                          => 'includes/models/product.php',
            'Models\Product_Meta'                     => 'includes/models/productmeta.php',
            'Models\Coupon'                           => 'includes/models/coupon.php',
            'Models\Coupon_Code'                      => 'includes/models/coupon-code.php',
            'Models\Coupon_Usage'                     => 'includes/models/coupon-usage.php',
            'Models\Affiliate_Click'                  => 'includes/models/affiliate-click.php',
            'Models\Cart'                             => 'includes/models/cart.php',
            'Models\Checkout'                         => 'includes/models/checkout.php',
            'Models\Checkout_Meta'                    => 'includes/models/checkoutmeta.php',
            'Models\Invoice'                          => 'includes/models/invoice.php',
            'Models\Invoice_Order'                    => 'includes/models/invoice-order.php',
            'Models\Commission'                       => 'includes/models/commission.php',
            'Models\Commission_Withdrawal'            => 'includes/models/commission-withdrawal.php',
            'Models\Order'                            => 'includes/models/order.php',
            'Models\Order_Log'                        => 'includes/models/order-log.php',
            'Models\Order_Meta'                       => 'includes/models/ordermeta.php',
            'Models\Access'                           => 'includes/models/access.php',
            'Models\Access_Meta'                      => 'includes/models/accessmeta.php',
            'Models\Notification'                     => 'includes/models/notification.php',
            'Models\Event'                            => 'includes/models/event.php',
            'AdminTable\Products'                     => 'includes/admin-table/products.php',
            'AdminTable\Coupons'                      => 'includes/admin-table/coupons.php',
            'AdminTable\Orders'                       => 'includes/admin-table/orders.php',
            'AdminTable\Payments'                     => 'includes/admin-table/payments.php',
            'AdminTable\File_License'                 => 'includes/admin-table/file-license.php',
            'AdminTable\Coupon_Codes'                 => 'includes/admin-table/coupon-codes.php',
            'AdminTable\Addon'                        => 'includes/admin-table/addon.php',
            'Frontend\Register'                       => 'includes/frontend/register.php',
            'Frontend\Login'                          => 'includes/frontend/login.php',
            'Frontend\Dashboard'                      => 'includes/frontend/dashboard.php',
            'Frontend\Product'                        => 'includes/frontend/product.php',
            'Frontend\Reset_Password'                 => 'includes/frontend/reset-password.php',
            'Frontend\Affiliate_Product'              => 'includes/frontend/affiliate-product.php',
            'Frontend\Affiliate_Product_Id'           => 'includes/frontend/affiliate-product-id.php',
            'Frontend\Affiliate_Statistics'           => 'includes/frontend/affiliate-statistics.php',
            'Frontend\Affiliate_Commission'           => 'includes/frontend/affiliate-commission.php',
            'Frontend\Affiliate_Withdrawal'           => 'includes/frontend/affiliate-withdrawal.php',
            'Frontend\Aff'                            => 'includes/frontend/aff.php',
            'Frontend\Checkout'                       => 'includes/frontend/checkout.php',
            'Frontend\Renew'                          => 'includes/frontend/renew.php',
            'Frontend\Payment'                        => 'includes/frontend/payment.php',
            'Frontend\Transaction_Invoice'            => 'includes/frontend/transaction-invoice.php',
            'Frontend\Transaction_Order'              => 'includes/frontend/transaction-order.php',
            'Frontend\Transaction_Order_Id'           => 'includes/frontend/transaction-order-id.php',
            'Frontend\Profile'                        => 'includes/frontend/profile.php',
            'Frontend\Thanks'                         => 'includes/frontend/thanks.php',
            'Frontend\Order'                          => 'includes/frontend/order.php',
            'Payment_Method\Bacs'                     => 'includes/payment-method/bacs.php',
            'Payment_Method\Paypal'                   => 'includes/payment-method/paypal.php',
            'Rest_Api\File'                           => 'includes/rest-api/file.php',
            'Rest_Api\User'                           => 'includes/rest-api/user.php',
            'Notification\Email'                      => 'includes/notification/email.php',
            'Email\Customer\Register'                 => 'includes/email/customer/register.php',
            'Email\Customer\Place_Order'              => 'includes/email/customer/place-order.php',
            'Email\Customer\Invoice_Checking_Payment' => 'includes/email/customer/invoice-checking-payment.php',
            'Email\Customer\Invoice_Completed'        => 'includes/email/customer/invoice-completed.php',
            'Email\Customer\Invoice_Refunded'         => 'includes/email/customer/invoice-refunded.php',
            'Email\Customer\Invoice_Cancelled'        => 'includes/email/customer/invoice-cancelled.php',
            'Email\Customer\Invoice_Unpaid_Reminder'  => 'includes/email/customer/invoice-unpaid-reminder.php',
            'Email\Customer\Order_Expired_Reminder'   => 'includes/email/customer/order-expired-reminder.php',
            'Email\Customer\Order_Expired'            => 'includes/email/customer/order-expired.php',
            'Email\Affiliate\New_Lead'                => 'includes/email/affiliate/new-lead.php',
            'Email\Affiliate\New_Sales'               => 'includes/email/affiliate/new-sales.php',
            'Email\Affiliate\Commission_Paid'         => 'includes/email/affiliate/commission-paid.php',
            'Email\Admin\Register'                    => 'includes/email/admin/register.php',
            'Email\Admin\Place_Order'                 => 'includes/email/admin/place-order.php',
            'Email\Admin\Invoice_Checking_Payment'    => 'includes/email/admin/invoice-checking-payment.php',
            'Email\Admin\Invoice_Completed'           => 'includes/email/admin/invoice-completed.php',
            'Email\Admin\Affiliate_Commission'        => 'includes/email/admin/affiliate-commission.php',
        ];
    }

    /**
     * Load class.
     *
     * For a given class name, require the class file.
     *
     * @param  mixed $relative_class_name
     * @return void
     */
    private static function load_class($relative_class_name)
    {
        $classes_map = self::get_classes_map();

        if (isset($classes_map[$relative_class_name])) {
            $filename = SALESLOO_PATH . $classes_map[$relative_class_name];
        } else {
            $filename = strtolower(
                preg_replace(
                    ['/([a-z])([A-Z])/', '/_/', '/\\\/'],
                    ['$1-$2', '-', DIRECTORY_SEPARATOR],
                    $relative_class_name
                )
            );

            $filename = SALESLOO_PATH . $filename . '.php';
        }

        if (is_readable($filename)) {
            require $filename;
        }
    }


    /**
     * autoload
     *
     * For a given class, check if it exist and load it.
     * 
     * @param  mixed $class
     * @return void
     */
    private static function autoload($class)
    {
        if (0 !== strpos($class, __NAMESPACE__ . '\\')) {
            return;
        }

        $relative_class_name = preg_replace('/^' . __NAMESPACE__ . '\\\/', '', $class);

        $final_class_name = __NAMESPACE__ . '\\' . $relative_class_name;

        if (!class_exists($final_class_name)) {
            self::load_class($relative_class_name);
        }
    }
}
