<?php
/**
 * Simple Service Container for Dependency Injection
 *
 * @package AIPT\Core
 * @since 2.4.0
 */

namespace AIPT\Core;

class Container {

    private static $instances = array();
    private static $factories = array();
    private static $singletons = array();

    public static function register( string $class, callable $factory, bool $singleton = true ): void {
        self::$factories[ $class ] = $factory;
        self::$singletons[ $class ] = $singleton;
    }

    public static function get( string $class ) {
        if ( isset( self::$instances[ $class ] ) ) {
            return self::$instances[ $class ];
        }

        if ( isset( self::$factories[ $class ] ) ) {
            $instance = self::$factories[ $class ]( self::class );

            if ( self::$singletons[ $class ] ?? true ) {
                self::$instances[ $class ] = $instance;
            }

            return $instance;
        }

        if ( class_exists( $class ) ) {
            $instance = new $class();
            self::$instances[ $class ] = $instance;
            return $instance;
        }

        throw new \InvalidArgumentException( sprintf( 'Class %s is not registered in the container.', $class ) );
    }

    public static function has( string $class ): bool {
        return isset( self::$instances[ $class ] ) || isset( self::$factories[ $class ] ) || class_exists( $class );
    }

    public static function reset(): void {
        self::$instances = array();
    }

    public static function clear(): void {
        self::$instances = array();
        self::$factories = array();
        self::$singletons = array();
    }
}
