<?php

namespace Fab\Plugin\Helper;

! defined( 'WPINC ' ) or die;

/**
 * Singleton trait for Fab plugins
 *
 * @package    Fab
 * @subpackage Fab\Helper
 */
trait Singleton {

    /**
     * Instance of this class
     *
     * @var object
     */
    protected static $instance = null;

    /**
     * Get instance of the class
     * NOTE:
     * - Please use get_instance() instead of this method for controllers and apis.
     * - This method is only for direct access to the class instance (parent class).
     * - If you're using it under child class, there's pottentials that it returns the wrong instance.
     *
     * @return object Instance of the class
     */
    public static function getInstance() {
        if ( null === static::$instance ) {
            static::$instance = new static();
        }
        return static::$instance;
    }

    /**
     * Get instance of the class
     * - This method will grab existing instance of the class if it exists, otherwise it will create a new instance.
     * - by doing so, we can improve performance and memory usage.
     * - This method is common known as Just In Time (JIT) loading.
     *
     * @return object Instance of the class
     */
    public static function get_instance() {
        // Get class namespace - class_namespace will be used as the key of the context because it's unique.
        // We have both \Fab and \FabPremium namespace, so we need to check if the class is from \Fab or \FabPremium.
        $class_namespace = get_called_class();

        // Implement JIT loading for proper context of APIs and controllers.
        if ( strpos( $class_namespace, '\Api' ) !== false ) {
            $context                     = \FAB()->getApis();
            $controller                  = isset( $context[ $class_namespace ] ) ? $context[ $class_namespace ] : new $class_namespace();
            $context[ $class_namespace ] = $controller;
            \FAB()->setApis( $context );
        } else {
            $context                     = \FAB()->getControllers();
            $controller                  = isset( $context[ $class_namespace ] ) ? $context[ $class_namespace ] : new $class_namespace();
            $context[ $class_namespace ] = $controller;
            \FAB()->setControllers( $context );
        }

        // Return controller instance.
        return $controller;
    }
}
