<?php
/**
 * Copyright since 2025 InPost S.A.
 *
 * For the full license information, please view the LICENSE file bundled with the module.
 *
 * @author InPost S.A.
 * @copyright since 2025 InPost S.A.
 * @license MIT
 */

declare(strict_types=1);

namespace InPost\International\Storage;

use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\SessionInterface;

if (!defined('_PS_VERSION_')) {
    exit;
}

final class SessionStorage implements StorageInterface
{
    public const SESSION_NAMESPACE = '_inpost_intl';

    /**
     * @var RequestStack
     */
    private $requestStack;

    /**
     * @var string
     */
    private $namespace;

    /**
     * @var SessionInterface|null
     */
    private $session;

    public function __construct(RequestStack $requestStack, string $namespace = self::SESSION_NAMESPACE)
    {
        $this->requestStack = $requestStack;
        $this->namespace = $namespace;
    }

    /**
     * {@inheritDoc}
     */
    public function get(string $key)
    {
        return $this->getSession()->get($this->namespace . '/' . $key);
    }

    /**
     * {@inheritDoc}
     */
    public function remove(string $key)
    {
        return $this->getSession()->remove($this->namespace . '/' . $key);
    }

    public function set(string $key, $value): void
    {
        $this->getSession()->set($this->namespace . '/' . $key, $value);
    }

    private function getSession(): SessionInterface
    {
        if (isset($this->session)) {
            return $this->session;
        }

        $request = $this->requestStack->getCurrentRequest();

        if (null === $request || !$request->hasSession()) {
            throw new \RuntimeException('Session is not available.');
        }

        $session = $request->getSession();

        if (!$session->isStarted()) {
            $session->start();
        }

        return $this->session = $session;
    }
}
