<?php
/**
 * @copyright (c) Kufer Software GmbH, Loisachstrasse 4, D-84453 Mühldorf
 */

declare(strict_types = 1);

namespace Kufer\Web\Classes\Dbfilter\RegisteredCall;

use Kufer\Web\Classes\Dbfilter\AbstractSQLFilter;
use Kufer\Web\Classes\Dbfilter\SQLFilterUtils;
use Kufer\Web\Classes\Stream\IterableStream;

class RegisteredDBCallString extends RegisteredDBCall
{
  public function getType(): int
  {
    return \Kufer\Web\Classes\Dbfilter\AbstractSQLFilter::TYPE_STRING;
  }

  public function getCapabilities(): int
  {
    return static::SUPPORTS_EQUALS
      | static::SUPPORTS_EQUALS_DEFAULT
      | static::SUPPORTS_GREATER
      | static::SUPPORTS_GREATER_DEFAULT
      | static::SUPPORTS_LESS
      | static::SUPPORTS_LESS_DEFAULT
      | static::SUPPORTS_IN
      | static::SUPPORTS_IN_DEFAULT
      | static::SUPPORTS_CONTAINS
      | static::SUPPORTS_LIKE;
  }

  public function equals(\Kufer\Web\Classes\Dbfilter\AbstractSQLFilter $filter, $value): callable
  {
    return $this->equalsDefault($filter, $value, $this->default);
  }

  public function equalsDefault(AbstractSQLFilter $filter, $value, $default): callable
  {
    if (\is_null($value)) {
      return SQLFilterUtils::filterEqualsStringNull($this->table, $this->column);
    }

    return SQLFilterUtils::filterEqualsStringDefault($this->table, $this->column, $value, $default);
  }

  public function in(\Kufer\Web\Classes\Dbfilter\AbstractSQLFilter $filter, iterable $value): callable
  {
    return $this->inDefault($filter, $value, $this->default);
  }

  public function inDefault(AbstractSQLFilter $filter, iterable $value, $default): callable
  {
    return SQLFilterUtils::filterInStringDefault($this->table, $this->column, \is_array($value) ? $value : (new IterableStream($value))->toArray(), $default);
  }

  public function contains(AbstractSQLFilter $filter, $value): callable
  {
    return $this->like($filter, "%$value%");
  }

  public function like(\Kufer\Web\Classes\Dbfilter\AbstractSQLFilter $filter, $value): callable
  {
    $trimmedValue = \trim($value);
    if (!$filter->isInverse() && ($trimmedValue === '%' || $trimmedValue === '%%')) {
      
      return \FunctionOperations::identity();
    }

    return SQLFilterUtils::filterCaseInsensitiveLike($this->table, $this->column, $value);
  }

  public function less(\Kufer\Web\Classes\Dbfilter\AbstractSQLFilter $filter, $value): callable
  {
    return $this->lessDefault($filter, $value, $this->default);
  }

  public function lessDefault(AbstractSQLFilter $filter, $value, $default): callable
  {
    return SQLFilterUtils::filterLessStringDefault($this->table, $this->column, $value, $default);
  }

  public function greater(\Kufer\Web\Classes\Dbfilter\AbstractSQLFilter $filter, $value): callable
  {
    return $this->greaterDefault($filter, $value, $this->default);
  }

  public function greaterDefault(AbstractSQLFilter $filter, $value, $default): callable
  {
    return SQLFilterUtils::filterGreaterStringDefault($this->table, $this->column, $value, $default);
  }

  public function is(AbstractSQLFilter $filter): callable
  {
    throw new CallNotSupportedException('Abfrage is hier nicht unterstützt.');
  }

  public function isDefault(AbstractSQLFilter $filter, $default): callable
  {
    throw new CallNotSupportedException('Abfrage is hier nicht unterstützt.');
  }
}