/*
     Author: Bakhtier Gaibulloev
*/

/**
 *@param T type of stack items.
 */
export class Stack<T> {

    // =========================================================================================================================================================
    // Public properties
    // =========================================================================================================================================================

    // =========================================================================================================================================================
    // Private properties
    // =========================================================================================================================================================

    private _store: T[] = [];

    // ========================================================================================================================================================
    // Constructor
    // =========================================================================================================================================================

    // =========================================================================================================================================================
    // Public methods
    // =========================================================================================================================================================

    /**
     * Pushes value to stack
     * @param value
     */
    push(value: T) {
        this._store.push(value);
    }

    /**
     * The element is popped from the top of the stack and is removed from the same.
     */
    pop(): T | null {

        if (this._store.length > 0) {
            return this._store.pop();
        }

        return null;
    }

    /**
     * The method returns the element at the top of the Stack else returns NULL if the Stack is empty.
     */
    peek(): T | null {

        if (this._store.length > 0) {
            return this._store[0];
        }

        return null;
    }

    /**
     * Returns the size of stack
     */
    size(): number {

        return this._store.length;
    }

    /**
    * Returns array of all items
    */
    toArray(): T[] {
        return this._store;
    }

    // =========================================================================================================================================================
    // Private methods
    // =========================================================================================================================================================

}
