<?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\Index\Collection;

use Magento\Mray\Package\AbstractTree\Component\MagentoModule;
use Magento\Mray\Package\AbstractTree\Component\MagentoLibrary;
use Magento\Mray\Package\AbstractTree\Component\MagentoTheme;
use Magento\Mray\Package\AbstractTree\Component\MagentoLanguage;
use Magento\Mray\Package\AbstractTree\Component\MagentoSetup;
use Magento\Mray\Package\AbstractTree\Component\MagentoComponent;
use Magento\Mray\Package\AbstractTree\Node\Component;
use Magento\Mray\Package\AbstractTree\Identifier\Versioned;
use Magento\Mray\Index\Data\MagentoComponentMeta;
use function strtolower;

class MagentoComponents implements DataCollection
{
    /** @var Dictionary  */
    private $dictionary;
    /** @var array  */
    private $data = [];

    /**
     * @param Dictionary|null $dictionary
     */
    public function __construct(?Dictionary $dictionary = null)
    {
        $this->dictionary = $dictionary ?? new Dictionary();
    }

    /**
     * @param Component $c
     */
    public function register(Component $c): void
    {
        if ($c->identifier instanceof Versioned) {
            $i = (string)$c->identifier->identifier;
            $v = (string)$c->identifier->version;
        } else {
            $i = (string)$c->identifier;
            $v = null;
        }

        if (!$i) {
            return;
        }

        if ($c instanceof MagentoModule) {
            $t = MagentoComponentMeta::T_MODULE;
            $section = 'modules';
        } elseif ($c instanceof MagentoLibrary) {
            $t = MagentoComponentMeta::T_LIBRARY;
            $section = 'libraries';
        } elseif ($c instanceof MagentoTheme) {
            $t = MagentoComponentMeta::T_THEME;
            $section = 'themes';
        } elseif ($c instanceof MagentoLanguage) {
            $t = MagentoComponentMeta::T_LANGUAGE;
            $section = 'languages';
        } elseif ($c instanceof MagentoSetup) {
            $t = MagentoComponentMeta::T_SETUP;
            $section = 'setups';
        } elseif ($c instanceof MagentoComponent) {
            $t = MagentoComponentMeta::T_COMPONENT;
            $section = 'components';
        } else {
            return;
        }

        $meta = new MagentoComponentMeta([
            'identifier' => $i,
            'type' => $t,
            'distributionPackage' => (string)$c->getAttribute('distributionPackage') ?: null,
            'version' => $v,
            'namespaces' => $c->getAttribute('namespaces'),
            'path' => (string)$c->getAttribute('path') ?: null,
            'checksum' => (string)$c->getAttribute('checksum') ?:    null,
        ]);

        $idRef = $this->dictionary->write(strtolower((string)$i));
        $dataRef = $this->dictionary->write($meta->pack($this->dictionary));
        $this->data[$section][$idRef] = $dataRef;
    }

    /**
     * @return array
     */
    public function exportData(): array
    {
        return $this->data;
    }

    /**
     * @param array $data
     */
    public function importData(array $data): void
    {
        foreach ($data as $section => $sectionData) {
            foreach ($sectionData as $idRef => $dataRef) {
                $this->data[$section][$idRef] = $dataRef;
            }
        }
    }
}
