1:  2:  3:  4:  5:  6:  7:  8:  9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 
<?php

namespace ClassConfig;

use ClassConfig\Exceptions\MissingConfigException;

/**
 * Class Config
 * @package ClassConfig
 */
abstract class AbstractConfig
{
    /**
     * @var object
     */
    protected $___owner;

    /**
     * @var null|AbstractConfig
     */
    protected $___parent;

    /**
     * @var null|string
     */
    protected $___key;

    /**
     * AbstractConfig constructor.
     *
     * @param object $owner
     * @param AbstractConfig|null $parent
     * @param string|null $key
     */
    public function __construct($owner, AbstractConfig $parent = null, string $key = null)
    {
        $this->___owner = $owner;
        $this->___parent = $parent;
        $this->___key = $key;
    }

    /**
     * @param string $key
     * @return bool
     */
    public function exists(string $key): bool
    {
        return property_exists($this, '__' . $key . '__');
    }

    /**
     * @param string $key
     * @return AbstractConfig
     * @throws MissingConfigException
     */
    public function depend(string $key): AbstractConfig
    {
        if (!isset($this->$key)) {
            $trail = [$key];

            $config = $this;
            while ($config->___parent) {
                $trail[] = $config->___key;
                $config = $config->___parent;
            }

            throw new MissingConfigException(array_reverse($trail));
        }
        return $this;
    }
}