<?php
namespace DynCom\mysyde\common\classes;
use DynCom\mysyde\common\interfaces\CriteriaHelperInterface;
use DynCom\mysyde\common\interfaces\ModelDBConfigInterface;

/**
 * Created by PhpStorm.
 * User: Micha
 * Date: 15.01.2015
 * Time: 21:43
 */
class SelectionCriteriaHelper implements CriteriaHelperInterface {

    /**
     * @param   array                  $allowedComparisons
     * @param   ModelDBConfigInterface $modelConfig
     * @param   array                  $criteriaArray
     *
     * @return  bool
     */

    protected $allowedComparisonOperators = array('IS NULL','IS NOT NULL','=','!=','<','>','>=','<=','IN','LIKE');

    /**
     * @param ModelDBConfigInterface $modelConfig
     * @param array $criteriaArray
     * @return bool
     */
    public function validateCriteria( ModelDBConfigInterface $modelConfig, array $criteriaArray ) {
        return $this->_validateCriteria($modelConfig, $criteriaArray);
    }

    /**
     * @param ModelDBConfigInterface $modelConfig
     * @param array $criteriaArray
     * @return bool
     */
    protected function _validateCriteria(ModelDBConfigInterface $modelConfig, array $criteriaArray ) {
        $fields     = $modelConfig->getMappedFields();
        $fieldNames = array();
        foreach ($fields as $fieldArr) {
            $fieldNames[] = $fieldArr['name'];
        }
        if (array_depth($criteriaArray) != 3) {
            return FALSE;
        }

        foreach ($criteriaArray as $disjunct) {
            foreach ($disjunct as $conjunct) {
                if (
                       (count($conjunct) < 2)
                    || (count($conjunct) > 3)
                    || (count($conjunct) > 2 && ($conjunct[1] == 'IS NULL' || $conjunct[1] == 'IS NOT NULL'))
                    || ($conjunct[1] == 'IN' && !(is_array($conjunct[2])))
                    || !(in_array($conjunct[0], $fieldNames))
                    || !(in_array($conjunct[1], $this->allowedComparisonOperators))
                    || !(in_array($conjunct[1], $modelConfig->getAllowedComparisonOperators()))
                ) {
                    return FALSE;
                }
            }
        }
        return TRUE;
    }

    /**
     * @param ModelDBConfigInterface $mapToConfig
     * @param ModelDBConfigInterface $mapFromConfig
     * @param array $criteriaFieldMappings
     * @return bool
     */
    protected function _validateCriteriaFieldMappings( ModelDBConfigInterface $mapToConfig, ModelDBConfigInterface $mapFromConfig, array $criteriaFieldMappings ) {

        $mapToFields     = $mapToConfig->getMappedFields();
        $mapToFieldNames = array();
        foreach ($mapToFields as $toFieldArr) {
            $mapToFieldNames[] = $toFieldArr['name'];
        }

        $mapFromFields     = $mapFromConfig->getMappedFields();
        $mapFromFieldNames = array();
        foreach ($mapFromFields as $fromFieldArr) {
            $mapFromFieldNames[] = $fromFieldArr['name'];
        }

        foreach ($criteriaFieldMappings as $fieldMapping) {
            if (
                   ($mapFromConfig->getAllowedComparisonOperators() !== $mapToConfig->getAllowedComparisonOperators())
                || (count($fieldMapping) < 2)
                || (count($fieldMapping) > 3)
                || (count($fieldMapping) > 2 && ($fieldMapping[1] == 'IS NULL' || $fieldMapping[1] == 'IS NOT NULL'))
                || ($fieldMapping[1] == 'IN' && !(is_array($fieldMapping[2])))
                || !(in_array($fieldMapping[0], $mapToFieldNames))
                || !(in_array($fieldMapping[1], $this->allowedComparisonOperators))
                || !(in_array($fieldMapping[1], $mapFromConfig->getAllowedComparisonOperators()))
                || ((count($fieldMapping) > 2) && !(in_array($fieldMapping[2], $mapFromFieldNames)))
            ) {
                return FALSE;
            }
        }

        return TRUE;

    }

    /**
     * @param ModelDBConfigInterface $mapToConfig
     * @param ModelDBConfigInterface $mapFromConfig
     * @param array $criteriaFieldMappings
     * @return bool
     */
    public function validateCriteriaFieldMappings( ModelDBConfigInterface $mapToConfig, ModelDBConfigInterface $mapFromConfig, array $criteriaFieldMappings ) {

        return $this->_validateCriteriaFieldMappings($mapToConfig,$mapFromConfig,$criteriaFieldMappings);

    }
}