<?php

namespace CookieSession;

class Session extends AbstractSession
{
    /**
     * @return array
     */
    public function all()
    {
        $result = [];

        foreach($this->session as $key => $value)
        {
            $result[$key] = $this->safeGet($key);
        }

        return $result;
    }


    /**
     * @return array
     */
    public function raw()
    {
        return $this->session;
    }


    /**
     * @param $key
     *
     * @return bool
     */
    public function del($key)
    {
        $result = false;

        if(isset($this->session[$key]))
        {
            unset($this->session[$key]);

            $result = true;
        }

        return $result;
    }


    /**
     * @param      $key
     * @param null $default
     *
     * @return null
     */
    public function get($key, $default = null)
    {
        return isset($this->session[$key]) ? $this->safeGet($key) : $default;
    }


    /**
     * @param      $key
     * @param null $value
     *
     * @return Session
     * @throws \Exception
     */
    public function put($key, $value = null)
    {
        return $this->safeSet($key, $value);
    }


    /**
     * @param      $key
     * @param null $default
     *
     * @return null
     */
    public function pull($key, $default = null)
    {
        $result = $default;

        if(isset($this->session[$key]))
        {
            $result = $this->safeGet($key);

            unset($this->session[$key]);
        }

        return $result;
    }


    /**
     * @param $key
     *
     * @return bool
     */
    public function has($key)
    {
        return isset($this->session[$key]);
    }


    /**
     * @return $this
     */
    public function clear()
    {
        $this->session = [];

        return $this;
    }


    /**
     * @param $key
     * @param $value
     *
     * @return $this
     * @throws \Exception
     */
    protected function safeSet($key, $value)
    {
        if(!is_string($value))
        {
            $this->session[$key] = $value;
        }
        else
        {
            $result = base64_encode($value);

            if(false === $result)
            {
                throw new \Exception("Unable to save the provided value, encoding failed.");
            }

            $this->session[$key] = $result;
        }

        return $this;
    }


    /**
     * @param $key
     *
     * @return mixed
     */
    protected function safeGet($key)
    {
        if(is_string($this->session[$key]))
        {
            return base64_decode($this->session[$key]);
        }

        return $this->session[$key];
    }
}