<?php

namespace CouponsPlus\App\Coupon\Tree\Testable;

use CouponsPlus\Original\Collections\Collection;

/**
 * I don't love singletons but since this is global state this will have to do
 */
class ProtectedGlobalState
{
    protected Collection $data;
    protected Collection $dataMap;

    public static function getInstance(): ProtectedGlobalState
    {
        static $instance = null;

        if ($instance === null) {
            $instance = new static();
        }

        return $instance;
    }

    protected function __construct()
    {
        $this->data = new Collection([]);
        $this->dataMap = new Collection([]);
    }

    /**
     * Returns the key to remove this data. With this key, the data cannot be removed.
     *
     * @param string $identifier Any string that identifies this type of data, eg: excluded_testables
     * @return string The key to remove this data
     */
    public function addData(string $identifier, $data) : string
    {
        if (!$this->data->get($identifier)) {
            $this->data->set($identifier, new Collection([]));
        }

        $stack = $this->data->get($identifier);
        $stack->push($data);

        $key = uniqid('', true);

        $this->dataMap->set($key, $identifier);

        return $key;
    }

    public function getData(string $identifier)
    {
        $stack = $this->data->get($identifier) ?? new Collection([]);

        return $stack->last();
    }

    public function removeData(string $key)
    {
        $identifier = $this->dataMap->get($key);

        if (!$identifier) {
            return;
        }

        /** @var Collection $stack */
        $stack = $this->data->get($identifier);
        $stack->removelast();

        if (!$stack->haveAny()) {
            $this->data->remove($identifier);
            $this->dataMap->remove($key);
        }

    }
}