<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Bridge\ProxyManager\Tests\LazyProxy;

require_once __DIR__.'/Fixtures/includes/foo.php';

use PHPUnit\Framework\TestCase;
use ProxyManager\Proxy\LazyLoadingInterface;
use ProxyManagerBridgeFooClass;
use Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * Integration tests for {@see \Symfony\Component\DependencyInjection\ContainerBuilder} combined
 * with the ProxyManager bridge.
 *
 * @author Marco Pivetta <ocramius@gmail.com>
 */
class ContainerBuilderTest extends TestCase
{
    public function testCreateProxyServiceWithRuntimeInstantiator()
    {
        $builder = new ContainerBuilder();

        $builder->setProxyInstantiator(new RuntimeInstantiator());

        $builder->register('foo1', ProxyManagerBridgeFooClass::class)->setFile(__DIR__.'/Fixtures/includes/foo.php')->setPublic(true);
        $builder->getDefinition('foo1')->setLazy(true);

        $builder->compile();

        /* @var $foo1 \ProxyManager\Proxy\LazyLoadingInterface|\ProxyManager\Proxy\ValueHolderInterface */
        $foo1 = $builder->get('foo1');

        $foo1->__destruct();
        $this->assertSame(0, $foo1::$destructorCount);

        $this->assertSame($foo1, $builder->get('foo1'), 'The same proxy is retrieved on multiple subsequent calls');
        $this->assertInstanceOf(ProxyManagerBridgeFooClass::class, $foo1);
        $this->assertInstanceOf(LazyLoadingInterface::class, $foo1);
        $this->assertFalse($foo1->isProxyInitialized());

        $foo1->initializeProxy();

        $this->assertSame($foo1, $builder->get('foo1'), 'The same proxy is retrieved after initialization');
        $this->assertTrue($foo1->isProxyInitialized());
        $this->assertInstanceOf(ProxyManagerBridgeFooClass::class, $foo1->getWrappedValueHolderValue());
        $this->assertNotInstanceOf(LazyLoadingInterface::class, $foo1->getWrappedValueHolderValue());

        $foo1->__destruct();
        $this->assertSame(1, $foo1::$destructorCount);
    }
}
