<?php

namespace idoit\Module\SyneticsFlows\Model\AttributeDataExtractor;

use idoit\Component\Property\Property;
use idoit\Module\Cmdb\Component\AttributeDataCollector\CollectorTypes\AbstractCollector;
use idoit\Module\SyneticsFlows\Model\AttributeDataExtractor\Type\BrowserLocation;
use idoit\Module\SyneticsFlows\Model\AttributeDataExtractor\Type\BrowserObject;
use idoit\Module\SyneticsFlows\Model\AttributeDataExtractor\Type\Dialog;
use idoit\Module\SyneticsFlows\Model\AttributeDataExtractor\Type\DialogCallbackData;
use idoit\Module\SyneticsFlows\Model\AttributeDataExtractor\Type\DialogData;
use idoit\Module\SyneticsFlows\Model\AttributeDataExtractor\Type\DialogList;
use idoit\Module\SyneticsFlows\Model\AttributeDataExtractor\Type\DialogPlus;
use idoit\Module\SyneticsFlows\Model\AttributeDataExtractor\Type\Multiselect;
use Throwable;

class Extractor implements ExtractorInterface
{
    /**
     * @param iterable $dataExtractors
     */
    public function __construct(private iterable $dataExtractors)
    {
    }

    /**
     * Need a factory as long we have the issue with the container that add-on services are not being loaded
     * on CLI context.
     *
     * @return self
     */
    public static function factory()
    {
        $extractors = [
            new BrowserLocation(),
            new BrowserObject(),
            new Dialog(),
            new DialogCallbackData(),
            new DialogData(),
            new DialogList(),
            new DialogPlus(),
            new Multiselect()
        ];

        return new self($extractors);
    }

    /**
     * @param AbstractCollector $dataCollector
     *
     * @return bool
     */
    public function supports(AbstractCollector $dataCollector): bool
    {
        foreach ($this->dataExtractors as $extractor) {
            if ($extractor instanceof ExtractorInterface && $extractor->supports($dataCollector)) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param Property          $property
     * @param AbstractCollector $dataCollector
     * @param string|null       $entryId
     *
     * @return array
     */
    public function extract(Property $property, AbstractCollector $dataCollector, ?string $entryId = null): array
    {
        try {
            foreach ($this->dataExtractors as $extractor) {
                if ($extractor instanceof ExtractorInterface && $extractor->supports($dataCollector)) {
                    return $extractor->extract($property, $dataCollector, $entryId);
                }
            }
        } catch (Throwable $exception) {
            // Do nothing
        }

        return [];
    }
}
