<?php

/**
 * Class ReaderTest
 *
 * LICENSE: This Software is the property of Lifestyle Webconsulting GmbH (Aschaffenburg, Germany)
 * and is protected by copyright law - it is NOT Freeware.
 *
 * Any unauthorized use of this software without a valid license
 * is a violation of the license agreement and will be prosecuted by
 * civil and criminal law.
 *
 * @copyright  2016 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 */

namespace LifeStyle\Tools\CachingBundle\Tests\Api\Data\Reader\Memcache;

use Symfony\Component\HttpFoundation\Request;
use LifeStyle\Tools\CachingBundle\Api\Manager as ApiManager;
use LifeStyle\Tools\CachingBundle\Api\Configuration\Configuration;
use LifeStyle\Tools\CachingBundle\Api\Data\Reader\Memcache\Reader as CacheReader;
use LifeStyle\Tools\CachingBundle\Annotations\LsCache;
use PHPUnit_Framework_TestCase;

/**
 * Class ReaderTest
 * @package LifeStyle\Tools\CachingBundle\Tests\Api\Data\Reader\Memcache
 */
class ReaderTest extends PHPUnit_Framework_TestCase
{
    public function testCacheReadHit()
    {
        $configData = [
            'cache_enabled' => true,
            'caching_engine' => 'memcache',
            'default_ttl' => 42,
            'memcache_host' => '127.0.0.1',
            'memcache_port' => '11211',
        ];
        $config = new Configuration($configData);

        $memcacheMock = $this->getMockBuilder(\Memcache::class)
            ->disableOriginalConstructor()
            ->setMethods([
                'get'
            ])
            ->getMock();
        $memcacheMock->expects($this->any())
            ->method('get')
            ->will($this->returnValue(serialize('##SOME CACHED CONTENT - "scriptTimeSec": 99.9999##')));
        $cacheReturnContentExpected = '##SOME CACHED CONTENT - "scriptTimeSec": 99.9999##';

        $apiManagerMock = $this->getMockBuilder(ApiManager::class)
            ->disableOriginalConstructor()
            ->setMethods([
                'getConfig',
                'getMemcache',
                'getMemcacheExtName',
                'scriptTimeSeconds'
            ])
            ->getMock();
        $apiManagerMock->expects($this->any())
            ->method('getConfig')
            ->will($this->returnValue($config));
        $apiManagerMock->expects($this->any())
            ->method('getMemcache')
            ->will($this->returnValue($memcacheMock));
        $apiManagerMock->expects($this->any())
            ->method('getMemcacheExtName')
            ->will($this->returnValue('memcache'));
        $apiManagerMock->expects($this->any())
            ->method('scriptTimeSeconds')
            ->will($this->returnValue(1.23));

        $request = new Request();

        $cacheReader = new CacheReader($apiManagerMock);
        $cacheReturn = $cacheReader->cacheRead($request);
        $this->assertEquals(null, $cacheReturn);

        $lsCache = new LsCache([
            'CacheTTL' => 42,
            'KeyHeader' => true
        ]);
        $request->attributes->set('_lsCache', $lsCache);
        $cacheReturn = $cacheReader->cacheRead($request);
        $this->assertEquals($cacheReturnContentExpected, $cacheReturn->getRequest()->attributes->get('_cachedContent'));
    }

    public function testCacheReadHitXml()
    {
        $configData = [
            'cache_enabled' => true,
            'caching_engine' => 'memcache',
            'default_ttl' => 42,
            'memcache_host' => '127.0.0.1',
            'memcache_port' => '11211',
        ];
        $config = new Configuration($configData);

        $memcacheMock = $this->getMockBuilder(\Memcache::class)
            ->disableOriginalConstructor()
            ->setMethods([
                'get'
            ])
            ->getMock();
        $memcacheMock->expects($this->any())
            ->method('get')
            ->will($this->returnValue(serialize('<test><scriptTimeSec>1.23</scriptTimeSec></test>')));
        $cacheReturnContentExpected = '<test><scriptTimeSec>1.23</scriptTimeSec></test>';

        $apiManagerMock = $this->getMockBuilder(ApiManager::class)
            ->disableOriginalConstructor()
            ->setMethods([
                'getConfig',
                'getMemcache',
                'getMemcacheExtName',
                'scriptTimeSeconds'
            ])
            ->getMock();
        $apiManagerMock->expects($this->any())
            ->method('getConfig')
            ->will($this->returnValue($config));
        $apiManagerMock->expects($this->any())
            ->method('getMemcache')
            ->will($this->returnValue($memcacheMock));
        $apiManagerMock->expects($this->any())
            ->method('getMemcacheExtName')
            ->will($this->returnValue('memcache'));
        $apiManagerMock->expects($this->any())
            ->method('scriptTimeSeconds')
            ->will($this->returnValue(1.23));

        $request = new Request();

        $cacheReader = new CacheReader($apiManagerMock);
        $cacheReturn = $cacheReader->cacheRead($request);
        $this->assertEquals(null, $cacheReturn);

        $lsCache = new LsCache([
            'CacheTTL' => 42,
            'KeyHeader' => true
        ]);
        $request->attributes->set('_lsCache', $lsCache);
        $request->attributes->set('_format', 'xml');
        $cacheReturn = $cacheReader->cacheRead($request);
        $this->assertEquals($cacheReturnContentExpected, $cacheReturn->getRequest()->attributes->get('_cachedContent'));
    }

    public function testCacheReadMiss()
    {
        $configData = [
            'cache_enabled' => true,
            'caching_engine' => 'memcache',
            'default_ttl' => 42,
            'memcache_host' => '127.0.0.1',
            'memcache_port' => '11211',
        ];
        $config = new Configuration($configData);

        $memcacheMock = $this->getMockBuilder(\Memcache::class)
            ->disableOriginalConstructor()
            ->setMethods([
                'get'
            ])
            ->getMock();
        $memcacheMock->expects($this->any())
            ->method('get')
            ->will($this->returnValue(false));

        $apiManagerMock = $this->getMockBuilder(ApiManager::class)
            ->disableOriginalConstructor()
            ->setMethods([
                'getConfig',
                'getMemcache',
                'getMemcacheExtName',
                'scriptTimeSeconds'
            ])
            ->getMock();
        $apiManagerMock->expects($this->any())
            ->method('getConfig')
            ->will($this->returnValue($config));
        $apiManagerMock->expects($this->any())
            ->method('getMemcache')
            ->will($this->returnValue($memcacheMock));
        $apiManagerMock->expects($this->any())
            ->method('getMemcacheExtName')
            ->will($this->returnValue('memcache'));
        $apiManagerMock->expects($this->any())
            ->method('scriptTimeSeconds')
            ->will($this->returnValue(1.23));

        $request = new Request();

        $cacheReader = new CacheReader($apiManagerMock);

        $lsCache = new LsCache([
            'CacheTTL' => 42,
            'KeyHeader' => true
        ]);
        $request->attributes->set('_lsCache', $lsCache);
        $cacheReturn = $cacheReader->cacheRead($request);
        $this->assertEquals(true, $cacheReturn->isBuildCache());
    }
}
