<?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\PickingOrderFilter\OrderFilterConditionQueryComponent;

use Shopware\Plugins\ViisonPickwareMobile\Components\QueryComponentArrayCoding\ComparisonQueryComponentArrayCoder;
use Shopware\Plugins\ViisonPickwareMobile\Components\QueryComponentArrayCoding\QueryComponentArrayDecodingPreprocessor;
use Shopware\Plugins\ViisonPickwareMobile\Components\QueryComponentArrayCoding\ScalarValueQueryComponentArrayCoder;

class LikeOperatorQueryComponentArrayDecodingPreprocessor implements QueryComponentArrayDecodingPreprocessor
{
    /**
     * @var string
     */
    const LIKE_OPERATOR_PREFIX = 'like_prefix';

    /**
     * @var string
     */
    const LIKE_OPERATOR_INFIX = 'like_infix';

    /**
     * @var string
     */
    const LIKE_OPERATOR_SUFFIX = 'like_suffix';

    /**
     * @var string
     */
    const NOT_LIKE_OPERATOR_INFIX = 'not_like_infix';

    /**
     * @var string
     */
    const NOT_LIKE_OPERATOR_PREFIX = 'not_like_prefix';

    /**
     * @var string
     */
    const NOT_LIKE_OPERATOR_SUFFIX = 'not_like_sufix';

    /**
     * @var string[]
     */
    const PROCESSABLE_LIKE_OPERATORS = [
        self::LIKE_OPERATOR_PREFIX,
        self::LIKE_OPERATOR_INFIX,
        self::LIKE_OPERATOR_SUFFIX,
        self::NOT_LIKE_OPERATOR_INFIX,
        self::NOT_LIKE_OPERATOR_PREFIX,
        self::NOT_LIKE_OPERATOR_SUFFIX,
    ];

    /**
     * {@inheritdoc}
     *
     * Matches any field comparison components whose operator is any of the processable `LIKE` operator variants and
     * normalizes those operators to a `LIKE` operator that is valid SQL.
     */
    public function process(array $arrayData)
    {
        $componentDataMatches = (
            isset($arrayData['type'])
            && $arrayData['type'] === ComparisonQueryComponentArrayCoder::CODABLE_TYPE
            && in_array($arrayData['operator'], self::PROCESSABLE_LIKE_OPERATORS)
            && isset($arrayData['rightOperand']['type'])
            && $arrayData['rightOperand']['type'] === ScalarValueQueryComponentArrayCoder::CODABLE_TYPE
        );
        if (!$componentDataMatches) {
            return $arrayData;
        }

        $escapedRightOperandValue = addcslashes($arrayData['rightOperand']['value'], '_%\\');
        switch ($arrayData['operator']) {
            case self::LIKE_OPERATOR_PREFIX:
                $arrayData['rightOperand']['value'] = $escapedRightOperandValue . '%';
                $arrayData['operator'] = 'LIKE';
                break;
            case self::LIKE_OPERATOR_INFIX:
                $arrayData['rightOperand']['value'] = '%' . $escapedRightOperandValue . '%';
                $arrayData['operator'] = 'LIKE';
                break;
            case self::LIKE_OPERATOR_SUFFIX:
                $arrayData['rightOperand']['value'] = '%' . $escapedRightOperandValue;
                $arrayData['operator'] = 'LIKE';
                break;
            case self::NOT_LIKE_OPERATOR_PREFIX:
                $arrayData['rightOperand']['value'] = $escapedRightOperandValue . '%';
                $arrayData['operator'] = 'NOT LIKE';
                break;
            case self::NOT_LIKE_OPERATOR_INFIX:
                $arrayData['rightOperand']['value'] = '%' . $escapedRightOperandValue . '%';
                $arrayData['operator'] = 'NOT LIKE';
                break;
            case self::NOT_LIKE_OPERATOR_SUFFIX:
                $arrayData['rightOperand']['value'] = '%' . $escapedRightOperandValue;
                $arrayData['operator'] = 'NOT LIKE';
                break;
        }

        return $arrayData;
    }
}
