<?php
/**
 * Класс словаря
 */

namespace freecms\components;

use Exception;

/**
 * Словарь (реализация интерфейса IDictionary
 */
class Dictionary implements IDictionary
{
    /**
     * @var array Содержимое словаря
     */
    private array $dict;

    public function __construct()
    {
        $this->dict = [];
    }

    /**
     * @inheritDoc
     */
    public function add(string $key, mixed $value): void
    {
        if (!$this->isKeyExists($key)) {
            $this->dict[$key] = $value;
        } else {
            $this->update($key, $value);
        }
    }

    /**
     * @inheritDoc
     */
    public function isKeyExists(string $key): bool
    {
        return array_key_exists($key, $this->dict);
    }

    /**
     * @inheritDoc
     */
    public function update(string $key, mixed $newValue): void
    {
        if (!$this->isKeyExists($key)) {
            $this->add($key, $newValue);
        } else {
            $this->dict[$key] = $newValue;
        }
    }

    /**
     * @inheritDoc
     * @throws Exception Если ключ не существует
     */
    public function get(string $key): mixed
    {
        if ($this->isKeyExists($key)) {
            return $this->dict[$key];
        } else {
            throw new Exception('Ключ "' . $key . '" не существует в этом словаре!', 0, null);
        }
    }

    /**
     * @inheritDoc
     * @throws Exception Если ключ не существует
     */
    public function clear(): void
    {
        $keys = $this->getAllKeys();

        foreach ($keys as $key) {
            $this->remove($key);
        }
    }

    /**
     * @inheritDoc
     */
    public function getAllKeys(): array
    {
        return array_keys($this->dict);
    }

    /**
     * @inheritDoc
     * @throws Exception Если ключ не существует
     */
    public function remove(string $key): void
    {
        if ($this->isKeyExists($key)) {
            unset($this->dict[$key]);
        } else {
            throw new Exception('Ключ "' . $key . '" не существует в этом словаре!', 0, null);
        }
    }
}
