<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Magento\Framework\App\Config;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Serialize\SerializerInterface;

/**
 * Initial configuration data container. Provides interface for reading initial config values
 */
class Initial
{
    /**
     * Cache identifier used to store initial config
     */
    public const CACHE_ID = 'initial_config';

    /**
     * Config data
     *
     * @var array
     */
    protected $_data = [];

    /**
     * Config metadata
     *
     * @var array
     */
    protected $_metadata = [];

    /**
     * @var SerializerInterface
     */
    private $serializer;

    /**
     * Initial constructor
     *
     * @param Initial\Reader $reader
     * @param \Magento\Framework\App\Cache\Type\Config $cache
     * @param SerializerInterface|null $serializer
     */
    public function __construct(
        \Magento\Framework\App\Config\Initial\Reader $reader,
        \Magento\Framework\App\Cache\Type\Config $cache,
        SerializerInterface $serializer = null
    ) {
        $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
            ->get(SerializerInterface::class);
        $data = $cache->load(self::CACHE_ID);
        if (!$data) {
            $data = $reader->read();
            $cache->save($this->serializer->serialize($data), self::CACHE_ID);
        } else {
            $data = $this->serializer->unserialize($data);
        }
        $this->_data = $data['data'];
        $this->_metadata = $data['metadata'];
    }

    /**
     * Get initial data by given scope
     *
     * @param string $scope Format is scope type and scope code separated by pipe: e.g. "type|code"
     * @return array
     */
    public function getData($scope)
    {
        [$scopeType, $scopeCode] = array_pad(explode('|', (string)$scope), 2, null);

        if (ScopeConfigInterface::SCOPE_TYPE_DEFAULT == $scopeType) {
            return $this->_data[$scopeType] ?? [];
        } elseif ($scopeCode) {
            return $this->_data[$scopeType][$scopeCode] ?? [];
        }
        return [];
    }

    /**
     * Get configuration metadata
     *
     * @return array
     */
    public function getMetadata()
    {
        return $this->_metadata;
    }
}
