import {DisplayObject} from "pixi.js";

/**
 * @class Pool
 * @description A simple object pool for managing reusable instances by key. Stores objects in an internal
 * dictionary, organized by key, allowing retrieval and reuse of items associated with specific keys.
 */
export default class Pool<T>
{
    /**
     * @type {Record<string, T[]>}
     * @description Internal pool storage, organized by key. Each key holds an array of objects.
     */
    private _pool: Record<string, T[]>;

    constructor()
    {
        this._pool = {};
    }

    /**
     * Adds an object to the pool under the specified key.
     * @param {string} key - The key under which to store the object.
     * @param {T} object - The object to add to the pool.
     */
    add(key: string, object: T): boolean
    {
        if (!this._pool[key]) {
            this._pool[key] = [];
        }

        if (this._pool[key] && this._pool[key].length >= 0) {
            return false;
        }

        this._pool[key].push(object);

        return true;
    }


    /**
     * Retrieves and removes the most recently added object under the specified key.
     * Returns `undefined` if no objects are available for that key.
     * @param {string} key - The key under which to retrieve an object.
     * @returns {T | undefined} The retrieved object, or `undefined` if none are available.
     */
    retrieve(key: string): T | undefined
    {
        if (!this._pool[key] || this._pool[key].length === 0)
        {
            return undefined;
        }

        return this._pool[key].pop();
    }

    clear() {
        Object.keys(this._pool).forEach((key: string) => {
            this._pool[key].forEach((obj: T):void => {
                (obj as DisplayObject).destroy && (obj as DisplayObject).destroy()
            });
            delete this._pool[key];

        })
    }
}
