<?php

namespace KupShop\I18nBundle\Tests;

use KupShop\KupShopBundle\Context\ContextManager;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Context\PriceLevelContext;
use KupShop\KupShopBundle\Context\UserContext;
use KupShop\PricelistBundle\Context\PricelistContext;

class ContextManagerTest extends \DatabaseTestCase
{
    /** @var \KupShop\I18nBundle\Context\ContextManager */
    private $contextManager;

    protected function setUp(): void
    {
        parent::setUp();

        $this->contextManager = $this->get(ContextManager::class);
    }

    public function testActivateContexts()
    {
        $languageContext = $this->get(LanguageContext::class);
        $currencyContext = $this->get(CurrencyContext::class);
        $priceLevelContext = $this->get(PriceLevelContext::class);
        $priceListContext = $this->get(PricelistContext::class);
        $userContext = $this->get(UserContext::class);

        $priceLevelContext->activate('20');
        $priceListContext->activate('3');

        $this->assertEquals('cs', $languageContext->getActiveId());
        $this->assertEquals('CZK', $currencyContext->getActiveId());
        $this->assertEquals(20, $priceLevelContext->getActiveId());
        $this->assertEquals(3, $priceListContext->getActiveId());
        $this->assertEquals(null, $userContext->getActiveId());

        $user = \User::createFromId(1);

        $result = $this->contextManager->activateContexts(
            [
                LanguageContext::class => 'sk',
                CurrencyContext::class => 'EUR',
                PriceLevelContext::class => ContextManager::CLEAR_CACHE,
                PricelistContext::class => ContextManager::CLEAR_CACHE,
                UserContext::class => $user,
            ],
            function () use ($userContext, $languageContext, $currencyContext, $priceLevelContext, $priceListContext) {
                return [
                    'language' => $languageContext->getActiveId(),
                    'currency' => $currencyContext->getActiveId(),
                    'priceLevel' => $priceLevelContext->getActiveId(),
                    'pricelist' => $priceListContext->getActiveId(),
                    'user' => $userContext->getActiveId(),
                ];
            }
        );

        $this->assertEquals('sk', $result['language']);
        $this->assertEquals('EUR', $result['currency']);
        $this->assertEquals(20, $result['priceLevel']);
        $this->assertEquals(null, $result['pricelist']);
        $this->assertEquals(1, $result['user']);

        $this->assertEquals('cs', $languageContext->getActiveId());
        $this->assertEquals('CZK', $currencyContext->getActiveId());
        $this->assertEquals(20, $priceLevelContext->getActiveId());
        $this->assertEquals(3, $priceListContext->getActiveId());
        $this->assertEquals(null, $userContext->getActiveId());
    }

    public function testActivateContextsLeaks()
    {
        /** @var LanguageContext $languageContext */
        $languageContext = $this->get(LanguageContext::class);
        /** @var CurrencyContext $currencyContext */
        $currencyContext = $this->get(CurrencyContext::class);
        /** @var PriceLevelContext $priceLevelContext */
        $priceLevelContext = $this->get(PriceLevelContext::class);
        /** @var PricelistContext $priceListContext */
        $priceListContext = $this->get(PricelistContext::class);

        $languageOutOfContextManager = $languageContext->getActiveId();
        $currencyOutOfContextManager = $currencyContext->getActiveId();
        $priceLevelOutOfContextManager = $priceLevelContext->getActiveId();
        $priceListOutOfContextManager = $priceListContext->getActiveId();

        $this->assertEquals('cs', $languageOutOfContextManager);
        $this->assertEquals('CZK', $currencyOutOfContextManager);
        $this->assertEquals(null, $priceLevelOutOfContextManager);
        $this->assertEquals(null, $priceListOutOfContextManager);

        $result = $this->contextManager->activateContexts(
            [
                PriceLevelContext::class => '20',
                PricelistContext::class => '3',
            ],
            function () use ($priceLevelContext, $priceListContext) {
                return [
                    'priceLevel' => $priceLevelContext->getActiveId(),
                    'pricelist' => $priceListContext->getActiveId(),
                ];
            }
        );

        $this->assertEquals(20, $result['priceLevel']);
        $this->assertEquals(3, $result['pricelist']);

        $this->assertEquals(null, $priceLevelContext->getActiveId());
        $this->assertEquals(null, $priceListContext->getActiveId());

        $priceLevelContext->clearCache();
        $priceListContext->clearCache();

        $this->assertEquals(null, $priceLevelContext->getActiveId());
        $this->assertEquals(null, $priceListContext->getActiveId());
    }

    public function testActivateOrderLeaks()
    {
        $priceLevelContext = $this->get(PriceLevelContext::class);
        $priceListContext = $this->get(PricelistContext::class);
        $userContext = $this->get(UserContext::class);

        $this->assertEquals(null, $priceLevelContext->getActiveId());
        $this->assertEquals(null, $priceListContext->getActiveId());
        $this->assertEquals(null, $userContext->getActiveId());

        $user = \User::createFromId(1);
        $order = \Order::createFromDbOrderNo('201300025');

        $result = $this->contextManager->activateOrder($order,
            function () use ($userContext, $priceLevelContext, $priceListContext) {
                return [
                    'priceLevel' => $priceLevelContext->getActiveId(),
                    'pricelist' => $priceListContext->getActiveId(),
                    'user' => $userContext->getActiveId(),
                ];
            }
        );

        $this->assertEquals(20, $result['priceLevel']);
        $this->assertEquals(null, $result['pricelist']);
        $this->assertEquals(1, $result['user']);

        $this->assertEquals(null, $priceLevelContext->getActiveId());
        $this->assertEquals(null, $priceListContext->getActiveId());
        $this->assertEquals(null, $userContext->getActiveId());

        $priceLevelContext->clearCache();
        $priceListContext->clearCache();

        $this->assertEquals(null, $priceLevelContext->getActiveId());
        $this->assertEquals(null, $priceListContext->getActiveId());
    }

    public function getDataSet()
    {
        return $this->getJsonDataSetFromFile();
    }
}
