<?php
// Copyright (c) Pickware GmbH. All rights reserved.
// This file is part of software that is released under a proprietary license.
// You must not copy, modify, distribute, make publicly available, or execute
// its contents or parts thereof without express permission by the copyright
// holder, unless otherwise permitted by law.

namespace Shopware\Plugins\ViisonPickwareMobile\Components;

use Shopware\Plugins\ViisonPickwareMobile\Components\QueryComponentArrayCoding\BooleanCompositionQueryComponentArrayCoder;
use Shopware\Plugins\ViisonPickwareMobile\Components\QueryComponentArrayCoding\ComparisonQueryComponentArrayCoder;

class QueryComponentFilter
{
    /**
     * @param array|null $encodedQueryComponent
     * @param callable $callback
     * @return null|array
     * @throws \Exception
     */
    public function filterComparisons($encodedQueryComponent, callable $callback)
    {
        if ($encodedQueryComponent === null) {
            return null;
        }
        if (!isset($encodedQueryComponent['type'])) {
            throw new \InvalidArgumentException(sprintf(
                (
                    'Method %s was passed an array-encoded QueryComponent which is missing field "type". ' .
                    'Please check whether the passed array $encodedQueryComponent is a valid array-encoded ' .
                    'QueryComponent.'
                ),
                __METHOD__
            ));
        }

        if ($encodedQueryComponent['type'] === ComparisonQueryComponentArrayCoder::CODABLE_TYPE) {
            return $callback($encodedQueryComponent) ? $encodedQueryComponent : null;
        }

        if ($encodedQueryComponent['type'] === BooleanCompositionQueryComponentArrayCoder::CODABLE_TYPE) {
            $filteredComparisons = array_values(array_filter(array_map(function (array $compositionComponent) use ($callback) {
                return $this->filterComparisons($compositionComponent, $callback);
            }, $encodedQueryComponent['compositionComponents'])));
            if (count($filteredComparisons) === 0) {
                return null;
            }
            if (count($filteredComparisons) === 1) {
                return $filteredComparisons[0];
            }

            $encodedQueryComponent['compositionComponents'] = $filteredComparisons;

            return $encodedQueryComponent;
        }

        throw new \InvalidArgumentException(sprintf(
            (
                'Method %s was passed an array-encoded QueryComponent of type %s which is not supported. ' .
                'Only types %s and %s are supported.'
            ),
            __METHOD__,
            $encodedQueryComponent['type'],
            BooleanCompositionQueryComponentArrayCoder::CODABLE_TYPE,
            ComparisonQueryComponentArrayCoder::CODABLE_TYPE
        ));
    }
}
