<?php
/**
 * Copyright 2020 Adobe
 * All Rights Reserved.
 *
 * NOTICE: Adobe permits you to use, modify, and distribute this file in
 * accordance with the terms of the Adobe license agreement accompanying
 * it.
 */
declare(strict_types=1);

namespace Magento\Mray\CodeStructuralElement\Php\Reflection\Context;

use Magento\Mray\CodeStructuralElement\Php\Reflection;
use Magento\Mray\CodeStructuralElement\Php\Reflection\Context;

class Closure implements Context
{
    use VariableScope {
        registerVariableDefinition as private registerOwnVariableDefinition;
    }

    /** @var Context  */
    private $outerContext;

    /**
     * @param Context $outerContext
     */
    public function __construct(Context $outerContext)
    {
        $this->outerContext = $outerContext;
        $thisVar = $outerContext->getVariable('this');
        if ($thisVar->isDefined()) {
            $this->variables['this'] = $thisVar;
        }
    }

    /**
     * @return Global_
     */
    public function getGlobal(): Global_
    {
        return $this->outerContext->getGlobal();
    }

    /**
     * @param Reflection\VariableDefinition $def
     */
    public function registerVariableDefinition(Reflection\VariableDefinition $def): void
    {
        if ($def instanceof Reflection\VariableDefinition\ClosureUse && $def->getAccessor()->resolvable()) {
            $accessPath = $def->getAccessor()->getPath();
            $expectedVar = array_shift($accessPath);
            if (!$expectedVar) {
                return;
            }

            $varName = $expectedVar->getName();
            $this->variables[$varName] = $this->outerContext->getVariable($varName)->redefine($def);
            return;
        }

        $this->registerOwnVariableDefinition($def);
    }
}
