<?php
/**
 * Author: Rymera Web Co
 *
 * @package SaveToWishlist\Abstracts
 */

namespace SaveToWishlist\Abstracts;

use SaveToWishlist\Traits\Magic_Getter_Setter;

/**
 * Abstract Singleton
 * Creates a singleton instance of a class.
 *
 * @since 1.0.0
 */
abstract class Singleton {

    use Magic_Getter_Setter;

    /**
     * Holds the class instance object
     *
     * @since 1.0.0
     *
     * @var Singleton $instance object
     */
    protected static $instance;

    /**
     * Holds the class data
     *
     * @since 1.0.0
     *
     * @var array $data The class data.
     */
    protected $data = array();

    /**
     * Return an instance of this class
     *
     * @since 1.0.0
     *
     * @param array ...$args The arguments to pass to the constructor.
     *
     * @return static The class instance object
     */
    public static function instance( ...$args ) {
        if ( ! static::$instance instanceof static ) {
            static::$instance = new static( ...$args );
        }

        return static::$instance;
    }

    /**
     * Prevent instance from being cloned.
     *
     * @since 1.0.0
     */
    protected function __clone() {
        // Do nothing.
    }

    /**
     * Prevent instance from being unserialized.
     *
     * @since 1.0.0
     *
     * @throws \Exception If the class is unserialized.
     */
    public function __wakeup() {
        throw new \Exception( 'Cannot unserialize a singleton.' );
    }

    /**
     * Protected constructor to prevent creating a new instance via 'new'.
     *
     * @since 1.0.0
     */
    protected function __construct() {
        // Initialize the singleton.
    }

    /**
     * Run method that is called when the class is instantiated.
     *
     * @since 1.0.0
     */
    public function run() {
        // Do something when the class is instantiated. This method is meant to be overridden in the subclass.
    }
}
