<?php
/**
 * Configuration class
 * @author Jérôme Brilland
 * @version 1.1
 * @copyright (c) 2019-2023, Jérôme Brilland
 * @license http://www.gnu.org/licenses/gpl.txt GNU General Public License
 */
class Configuration implements ArrayAccess, IteratorAggregate, Countable {

    /**
     * @access private
     */
    private $configurationHandler;

    /**
     * @param IConfigurationHandler configurationHandler
     * @access public
     */
    public function __construct( IConfigurationHandler $configurationHandler ) {
        $this->configurationHandler = $configurationHandler->load();
    }

    /**
     * @param string key
     * @return mixed
     * @access public
     */
    public function get( $key, $default = null ) {
        return $this->configurationHandler->get( $key, $default );
    }

    /**
     * Whether or not an offset exists.
     * @param mixed offset An offset to check for.
     * @return boolean True if the offset exists, false otherwise.
     * @access public
     */
    public function offsetExists( mixed $offset ): bool {
        return $this->configurationHandler->has( $offset );
    }

    /**
     * Returns the value at specified offset.
     * @param mixed offset The offset to retrieve.
     * @return mixed The value at specified offset.
     * @access public
     */
    public function offsetGet( mixed $offset ): mixed {
        if ( $this->configurationHandler->has( $offset ) ) {
            return $this->configurationHandler->get( $offset );
        } else {
            throw new OutOfBoundsException( 'Key ' . $offset . ' does not exist.' );
        }
    }

    /**
     * Assigns a value to the specified offset.
     * @param mixed offset The offset to assign the value to.
     * @param mixed value The value to set.
     * @access public
     */
    public function offsetSet( mixed $offset, mixed $value ): void {
        $this->configurationHandler->set( $offset, $value );
    }

    /**
     * Unsets an offset.
     * @param mixed offset The offset to unset.
     * @access public
     */
    public function offsetUnset( mixed $offset ): void {
        $this->configurationHandler->remove( $offset );
    }

    /**
     * @return Traversable
     * @access public
     */
    public function getIterator(): Traversable {
        return $this->configurationHandler->getIterator();
    }

    /**
     * @return int
     * @access public
     */
    public function count(): int {
        return count( $this->configurationHandler->getIterator() );
    }
}
