<?php
/**
 * @author Jaap Jansma <jaap.jansma@civicoop.org>
 * @license AGPL-3.0
 */

namespace Civi\DataProcessor\DataFlow\SqlDataFlow;

use CRM_Core_DAO;
use CRM_Core_Exception;
use CRM_Utils_Type;

/**
 * Use this clause to create a where on a civicrm multi value column, where values are seperated by
 * the \CRM_Core_DAO::VALUE_SEPARATOR character.
 *
 * Class SeperatorFieldWhereClause
 *
 * @package Civi\DataProcessor\DataFlow\SqlDataFlow
 */
class MultiValueFieldWhereClause extends AbstractWhereClause implements WhereClauseInterface {

  protected $table_alias;

  protected $field;

  protected $operator;

  protected $value;
  protected $valueType;

  public function __construct($table_alias, $field, $operator, $value, $valueType = 'String', $isJoinClause=FALSE) {
    $this->isJoinClause = $isJoinClause;
    $this->table_alias = $table_alias;
    $this->field = $field;
    $this->operator = $operator;
    $this->value = $value;
    $this->valueType = $valueType;
  }

  /**
   * Returns the where clause
   * E.g. contact_type = 'Individual'
   *
   * @return string
   */
  public function getWhereClause(): string {
    $clauses = array();
    if (!is_array($this->value)) {
      $this->value = array($this->value);
    }
    $combine = "OR";
    $includeNullStatement = false;
    foreach($this->value as $value) {
      $escapedValue = '';
      try {
        $escapedValue = CRM_Utils_Type::escape($value, $this->valueType);
      } catch (CRM_Core_Exception $e) {
      }
      $compareValue = "%". CRM_Core_DAO::VALUE_SEPARATOR.$escapedValue. CRM_Core_DAO::VALUE_SEPARATOR."%";
      switch ($this->operator) {
        case 'LIKE':
        case 'IN':
        case '=':
          $clauses[] = "`$this->table_alias`.`$this->field` LIKE  '$compareValue'";
          break;
        case 'NOT LIKE':
        case 'NOT IN':
        case '!=':
          $includeNullStatement = true;
          $combine = "AND";
          $clauses[] = "`$this->table_alias`.`$this->field` NOT LIKE '$compareValue'";
          break;
      }
    }
    if (count($clauses)) {
      $extraStatement = "";
      if ($includeNullStatement) {
        $extraStatement .= " OR `$this->table_alias`.`$this->field` IS NULL";
      }
      return "(" . implode(" $combine ", $clauses) . ")" . $extraStatement;
    }
    return "";
  }

}
