<?php

namespace CookieSession\Storage;

use CookieSession\Encrypter\Encrypter;
use Hashids\Hashids;

class StorageTest extends \PhpUnit_Framework_TestCase
{
    protected $encrypter;
    protected $storage;

    public function testStorageCompression()
    {
        $string = str_repeat('a', 50);

        $compressed = $this->getStorage()->set($string)->compress()->get();

        $this->assertEquals(6, strlen($compressed));
        $this->assertEquals($string, $this->getStorage()->set($compressed)->decompress()->get());
    }

    public function testStorageEncryption()
    {
        $string = 'Brown fox jumped over lazy dog using Lorem Ipsum';

        $encrypted = $this->getStorage()->set($string)->encrypt()->get();

        $this->assertEquals($string, $this->getStorage()->set($encrypted)->decrypt()->get());
    }

    public function testStorageEncoding()
    {
        $string = 'Hello World. I will be encoded for testing purposes. I contain special characters: % $ @ < </> and all of these would make browsers go nuts! :)';

        $encoded = $this->getStorage()->set($string)->encode()->get();

        $this->assertEquals($string, $this->getStorage()->set($encoded)->decode()->get());
    }

    public function testStorageEncryptionCompressionEncoding()
    {
        $original = 'Hello World. I will be encoded for testing purposes. I contain special characters: % $ @ < </> and all of these would make browsers go nuts! :)';

        $storage = $this->getStorage();

        $modified = $storage->set($original)->encrypt()->compress()->encode()->get();

        $this->assertNotEquals($modified, $original);
        $this->assertEquals($original, $storage->set($modified)->decode()->decompress()->decrypt()->get());
    }

    public function testSerialization()
    {
        $string = openssl_random_pseudo_bytes((1024 * 2)); // 2KB

        $storage = $this->getStorage();

        $serialized = $storage->serialize($string);

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

        $record = $serialized->at(0);

        $tz = new \DateTimeZone("UTC");
        $dt = \DateTime::createFromFormat('l g A', 'Saturday 10 PM', $tz);

        $cookie = $record->toCookie($dt, 'authstack.web');

        $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\Cookie', $cookie);
        $this->assertEquals('authstack.web', $cookie->getDomain());
    }


    /**
     * @return Storage
     */
    protected function getStorage()
    {
        if(!$this->storage instanceof Storage)
        {
            $this->storage = new Storage();

            $this->storage->setEncrypter($this->getEncrypter());
            $this->storage->setHashids($this->getHashids());
        }

        return $this->storage;
    }


    /**
     * @return Encrypter
     */
    protected function getEncrypter()
    {
        if(!$this->encrypter instanceof Encrypter)
        {
            $this->encrypter = new Encrypter();

            $this->encrypter->setMethod('aes-256-cbc');
            $this->encrypter->setSecret(openssl_random_pseudo_bytes(32));
            //$this->encrypter->setIV(openssl_random_pseudo_bytes(16));
            $this->encrypter->autoSetIV();
            $this->encrypter->setSignatureAlgo(OPENSSL_ALGO_SHA1);
            $this->encrypter->setPublicKey(file_get_contents(dirname(__FILE__) . DIRECTORY_SEPARATOR .'../../pki/public.crt'));
            $this->encrypter->setPrivateKey(file_get_contents(dirname(__FILE__) . DIRECTORY_SEPARATOR .'../../pki/private.pem'));
        }

        return $this->encrypter;
    }

    protected function getHashids()
    {
        return new Hashids('hKsUqLuBzF9z7rdI6MdLF2K0CFOsOmLz', 16, '0p3rc9y8e76vaxqs');
    }
}