<?php
/**
 * Registry Class
 *
 * @version     1.0.$Revision:$
 * @version     SVN: $Id:$
 * @package     bplan-base/globals
 * @subpackage  Registries
 * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
 * @copyright   Copyright (C) 2025, 2026 Wassilios Meletiadis <https://www.bplan-solutions.de/>
 * /Δ\
 */

namespace BplanBase\Globals\Registries;


use Illuminate\Support\Arr;
use InvalidArgumentException;
use RuntimeException;


/**
 * Registry Class
 *
 * @version     4.0.0 / 2026-03-06
 * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
 */
class Registry
{


/* +++ CLASS CONSTANTS +++ ++++++++++++++++++++++++++++++++++++++++++++++++++ */


/* +++ OBJECT MEMBERS +++ +++++++++++++++++++++++++++++++++++++++++++++++++++ */


/* +++ CLASS MEMBERS +++ ++++++++++++++++++++++++++++++++++++++++++++++++++++ */


    /**
     * Array mit readonly-Schlüsseln
     */
    private static array $_readonly = [];


    /**
     * Internes Registry-Array
     */
    private static array $_registry = [];


/* +++ OBJECT METHODS +++ +++++++++++++++++++++++++++++++++++++++++++++++++++ */


/* +++ CLASS METHODS +++ ++++++++++++++++++++++++++++++++++++++++++++++++++++ */


    /**
     * Gibt den vollständigen Registry-Array zurück
     *
     * @return      array
     *
     * @version     1.0.0 / 2025-05-20
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    public static function all(): array
    {
        return self::$_registry;

    } // all()


    /**
     * Leert die Registry und gibt den vollständigen, ursprünglichen Inhalt zurück
     *
     * @return      array
     *
     * @version     1.1.0 / 2025-07-16
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    public static function flush(): array
    {
        $return = self::$_registry;

        self::$_readonly = [];
        self::$_registry = [];

        return $return;

    } // flush()


    /**
     * Schlüssel und zugehörigen Wert löschen
     *
     * @param       string $key
     *
     * @param       bool $force
     *
     * @throws      RuntimeException
     *
     * @return      mixed Der vorherige Wert oder NULL
     *
     * @version     2.0.0 / 2026-03-06
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    public static function forget(string $key, bool $force = false): mixed
    {
        if ($force === false && Arr::has(self::$_readonly, $key)) {
            throw new RuntimeException('The key '.$key.' is readonly and cannot be removed.');
        }
        $value = Arr::get(self::$_registry, $key, null);

        Arr::forget(self::$_registry, $key);
        Arr::forget(self::$_readonly, $key);

        return $value;

    } // forget()


    /**
     * Wert(e) lesen
     *
     * @param       string $key
     *
     * @param       mixed $default
     *
     * @return      mixed
     *
     * @version     1.0.0 / 2025-05-19
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    public static function get(string $key, mixed $default = null): mixed
    {
        return Arr::get(self::$_registry, $key, $default);

    } // get()


    /**
     * Prüfen ob ein Wert zu einem Schlüssel existiert
     *
     * @param       string $key
     *
     * @param       mixed $default
     *
     * @return      bool
     *
     * @version     1.0.0 / 2025-07-16
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    public static function has(string $key, mixed $default = null): bool
    {
        return Arr::has(self::$_registry, $key, $default);

    } // has()


    /**
     * Wert(e) setzen
     *
     * @param       string $key
     *
     * @param       mixed $value
     *
     * @param       bool $readonly
     *
     * @throws      RuntimeException
     *
     * @return      void
     *
     * @version     1.0.0 / 2025-05-19
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    public static function put(string $key, mixed $value, bool $readonly = false): void
    {
        if (Arr::has(self::$_readonly, $key)) {
            throw new RuntimeException('The key '.$key.' is readonly and cannot be modified.');
        }
        Arr::set(self::$_registry, $key, $value);

        if ($readonly === true) {
            Arr::set(self::$_readonly, $key, true);
        }
    } // put()


} // class Registry {}
