<?php

namespace CookieSession;

//use Symfony\Component\HttpFoundation\Request;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Cookie;

class SessionTest extends \PhpUnit_Framework_TestCase
{
    public function testInitialization()
    {
        $session = $this->getSession();

        $this->assertInstanceOf('CookieSession\\Session', $session);
    }

    public function testPut()
    {
        $session = $this->getSession();

        $session->put('k', 'value');

        $this->assertEquals($session->get('k'), 'value');
    }

    public function testPull()
    {
        $session = $this->getSession();

        $session->put('k', 'value');

        $pulled = $session->pull('k');

        $this->assertEquals($pulled, 'value');
        $this->assertFalse($session->has('k'));
    }

    public function testSerialization()
    {
        $session = $this->getSession();
        $session_data = (openssl_random_pseudo_bytes(1024 * 16));

        $session->put('long_value', $session_data);

        $serialized = $session->serialize();

        $expiry = $this->getExpiry();

        $this->assertInstanceOf('CookieSession\\Storage\\Serialization\\Collection', $serialized);
        $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\Cookie', $serialized->toCookie('session_cookie', $expiry, 'authstack.co.uk'));
        $this->assertTrue(is_array($serialized->toCookies($expiry, 'authstack.co.uk')));
    }

    public function testSerializationWithArrayData()
    {
        $session = $this->getSession();

        $session->put('email', 'someone@something.com');
        $session->put('attributes', ['name' => 'Lorem', 'lname' => 'Ipsum']);

        $serialized = $session->serialize();

        $this->assertInstanceOf('CookieSession\\Storage\\Serialization\\Collection', $serialized);
    }

    public function testUnserialization()
    {
        $request = $this->getRequest();
        $session = $this->getSession()->unserializeFromRequest($request, true);

        if(!$session->isStarted())
        {
            die('failed to start the session: ' . $session->getLastError());
        }


        $this->assertInstanceOf('CookieSession\\Session', $session);
        $this->assertEquals('someone@something.com', $session->get('email'));
        $this->assertTrue(is_array($session->get('attributes')));
    }

    public function testToCookies()
    {
        $session = $this->getSession();

        $session->put('name', 'Lorem Ipsum');
        $session->put('email', 'someone@something.com');
        $session->put('attributes', ['name' => 'Lorem', 'lname' => 'Ipsum']);

        $cookies = $session->toCookies();

        $this->assertTrue(is_array($cookies));
    }

    protected function getRequest()
    {
        $session = $this->getSession();

        $session->put('email', 'someone@something.com');
        $session->put('attributes', ['name' => 'Lorem', 'lname' => 'Ipsum']);
        $session->put('long_piece_of_info', openssl_random_pseudo_bytes(1024*16));

        $serialized = $session->serialize();

        $metadata = $serialized->toCookie($session->getCookieName(), $this->getExpiry(), 'authstack.co.uk');
        $iv = $session->getIVCookie();
        $data = $serialized->toCookies($this->getExpiry(), 'authstack.co.uk');

        $cookies = array_merge([$metadata, $iv], $data);

        $cookie_arr = [];

        foreach($cookies as $cookie)
        {
            /** @var $cookie Cookie */
            $cookie_arr[$cookie->getName()] = $cookie->getValue();
        }

        $request = new Request([], [], [], $cookie_arr);

        return $request;
    }

    protected function getExpiry()
    {
        $tz = new \DateTimeZone("UTC");

        return new \DateTime("+1 day", $tz);
    }

    protected function getSession()
    {
        $config = require(__DIR__ . '/../config.php');

        return Session::initialize($config);
    }
}