<?php
/**
 * Singleton Trait.
 *
 * Provides singleton pattern implementation for classes. Uses a static
 * array to store instances keyed by class name.
 *
 * @package   Agenistrator
 * @since     1.0.0
 * @author    Alex Ruban <alex@maximum.guru>
 * @author    Maximum Software Inc <contact@maximum.software>
 * @license   GPL-3.0-only
 * @link      https://agenistrator.com/
 *
 * SPDX-FileCopyrightText: 2025-2026 Alex Ruban <alex@maximum.guru>
 * SPDX-FileCopyrightText: 2025-2026 Maximum Software Inc <contact@maximum.software>
 * SPDX-License-Identifier: GPL-3.0-only
 */

namespace Agenistrator;

// Direct access prevention
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Singleton trait.
 */
trait Singleton {
	/**
	 * Array of instances, keyed by class name
	 * @var array
	 */
	private static $instances = array();

	/**
	 * Get the single instance of the class
	 *
	 * @return object The singleton instance
	 * @since     1.0.0
	 */
	public static function get_instance() {
		$class = get_called_class();

		if ( ! isset( self::$instances[ $class ] ) ) {
			self::$instances[ $class ] = new static();
		}

		return self::$instances[ $class ];
	}

	/**
	 * Private constructor to prevent direct instantiation
	 * Calls init() method for class-specific initialization
	 *
	 * @return void
	 */
	final private function __construct() {
		$this->init();
	}

	/**
	 * Initialization method for classes using this trait
	 * Override this method in user class to perform initialization
	 *
	 * @return void
	 * @since     1.0.0
	 */
	protected function init() {
		// Default empty implementation - override in user class
	}

	/**
	 * Prevent cloning of the instance
	 *
	 * @return void
	 */
	private function __clone() {
		// Prevent cloning of the instance
		throw new \Exception( 'Cannot clone singleton' );
	}

	/**
	 * Prevent unserializing of the instance
	 *
	 * @return void
	 * @since     1.0.0
	 */
	public function __wakeup() {
		// Prevent unserializing of the instance
		throw new \Exception( 'Cannot unserialize singleton' );
	}
}
