<?php declare(strict_types=1);
/**
 * Banker
 *
 * A Caching library implementing psr/cache
 *
 * PHP version 7.0
 *
 * @package     Banker
 * @author      Timothy J. Warren <tim@timshomepage.net>
 * @copyright   2016  Timothy J. Warren
 * @license     http://www.opensource.org/licenses/mit-license.html  MIT License
 * @version     1.0.0
 * @link        https://git.timshomepage.net/timw4mail/banker
 */

namespace Aviat\Banker\Tests;

use Aviat\Banker\Item;
use Aviat\Banker\Driver\NullDriver;
use Aviat\Banker\Tests\Friend;
use PHPUnit\Framework\TestCase;

use DateTime;
use DateInterval;

class ItemTest extends TestCase {

	protected $key = 'foo';
	protected $item;
	protected $driver;

	public function setUp()
	{
		$this->driver = new NullDriver();
		$this->item = new Item($this->driver, $this->key);
	}

	public function testGetKey()
	{
		$this->assertEquals($this->key, $this->item->getKey());
	}

	public function testGet()
	{
		// No value set yet
		$this->assertNull($this->item->get());

		// Set a value
		$this->item->set('bar')
			->save();

		$this->assertEquals('bar', $this->item->get());
	}

	public function testExpiresAt()
	{
		$time = new DateTime("Next Tuesday");
		$expected = $time->getTimestamp();
		$this->item->expiresAt($time);
		$friend = new Friend($this->item);
		$this->assertEquals($expected, $friend->expiresAt, "DateTimeInterface");

		$time2 = strtotime("July 16, 2024");
		$this->item->expiresAt($time2);
		$friend2 = new Friend($this->item);
		$this->assertEquals($time2, $friend2->expiresAt, "Unix Timestamp");
	}

	public function testExpiresAfter()
	{
		$interval = new DateInterval('P5W');
		$expected = (int) $interval->format("%s");
		$this->item->expiresAfter($interval);
		$friend = new Friend($this->item);
		$this->assertEquals($expected, $friend->ttl);

		$interval2 = 500;
		$this->item->expiresAfter($interval2);
		$friend2 = new Friend($this->item);
		$this->assertEquals($interval2, $friend2->ttl);
	}

	public function testSaveWithExpiresAt()
	{
		$this->setUp();

		$expires = new DateTime("6 weeks");
		$this->item->expiresAt($expires);

		$this->item->set('barbazfoo');

		$result = $this->item->save();

		$this->assertTrue($result);
		$this->assertTrue($this->item->isHit());
		$this->assertEquals('barbazfoo', $this->item->get());
	}

	public function testSaveWithExpiresAfter()
	{
		$this->setUp();

		$interval = new DateInterval('P2D');
		$expected = $interval->format("%s");
		$this->item->expiresAfter($interval);
		$friend = new Friend($this->item);
		$this->assertEquals($expected, $friend->ttl);

		$expected = [
			'foo' => [
				'bar' => []
			],
			'baz' => (object) []
		];
		$this->item->set($expected);

		$result = $this->item->save();

		$this->assertTrue($result);
		$this->assertTrue($this->item->isHit());
		$this->assertEquals($expected, $this->item->get());
	}
}