<?php
declare (strict_types=1);
namespace MailPoetVendor\Doctrine\ORM\Query;
if (!defined('ABSPATH')) exit;
use MailPoetVendor\Doctrine\ORM\Configuration;
use MailPoetVendor\Doctrine\ORM\EntityManagerInterface;
use MailPoetVendor\Doctrine\ORM\Query\Filter\SQLFilter;
use InvalidArgumentException;
use function assert;
use function ksort;
class FilterCollection
{
 public const FILTERS_STATE_CLEAN = 1;
 public const FILTERS_STATE_DIRTY = 2;
 private $config;
 private $em;
 private $enabledFilters = [];
 private $suspendedFilters = [];
 private $filterHash = '';
 private $filtersState = self::FILTERS_STATE_CLEAN;
 public function __construct(EntityManagerInterface $em)
 {
 $this->em = $em;
 $this->config = $em->getConfiguration();
 }
 public function getEnabledFilters()
 {
 return $this->enabledFilters;
 }
 public function getSuspendedFilters() : array
 {
 return $this->suspendedFilters;
 }
 public function enable($name)
 {
 if (!$this->has($name)) {
 throw new InvalidArgumentException("Filter '" . $name . "' does not exist.");
 }
 if (!$this->isEnabled($name)) {
 $filterClass = $this->config->getFilterClassName($name);
 assert($filterClass !== null);
 $this->enabledFilters[$name] = new $filterClass($this->em);
 // In case a suspended filter with the same name was forgotten
 unset($this->suspendedFilters[$name]);
 // Keep the enabled filters sorted for the hash
 ksort($this->enabledFilters);
 $this->setFiltersStateDirty();
 }
 return $this->enabledFilters[$name];
 }
 public function disable($name)
 {
 // Get the filter to return it
 $filter = $this->getFilter($name);
 unset($this->enabledFilters[$name]);
 $this->setFiltersStateDirty();
 return $filter;
 }
 public function suspend(string $name) : SQLFilter
 {
 // Get the filter to return it
 $filter = $this->getFilter($name);
 $this->suspendedFilters[$name] = $filter;
 unset($this->enabledFilters[$name]);
 $this->setFiltersStateDirty();
 return $filter;
 }
 public function restore(string $name) : SQLFilter
 {
 if (!$this->isSuspended($name)) {
 throw new InvalidArgumentException("Filter '" . $name . "' is not suspended.");
 }
 $this->enabledFilters[$name] = $this->suspendedFilters[$name];
 unset($this->suspendedFilters[$name]);
 // Keep the enabled filters sorted for the hash
 ksort($this->enabledFilters);
 $this->setFiltersStateDirty();
 return $this->enabledFilters[$name];
 }
 public function getFilter($name)
 {
 if (!$this->isEnabled($name)) {
 throw new InvalidArgumentException("Filter '" . $name . "' is not enabled.");
 }
 return $this->enabledFilters[$name];
 }
 public function has($name)
 {
 return $this->config->getFilterClassName($name) !== null;
 }
 public function isEnabled($name)
 {
 return isset($this->enabledFilters[$name]);
 }
 public function isSuspended(string $name) : bool
 {
 return isset($this->suspendedFilters[$name]);
 }
 public function isClean()
 {
 return $this->filtersState === self::FILTERS_STATE_CLEAN;
 }
 public function getHash()
 {
 // If there are only clean filters, the previous hash can be returned
 if ($this->filtersState === self::FILTERS_STATE_CLEAN) {
 return $this->filterHash;
 }
 $filterHash = '';
 foreach ($this->enabledFilters as $name => $filter) {
 $filterHash .= $name . $filter;
 }
 $this->filterHash = $filterHash;
 $this->filtersState = self::FILTERS_STATE_CLEAN;
 return $filterHash;
 }
 public function setFiltersStateDirty()
 {
 $this->filtersState = self::FILTERS_STATE_DIRTY;
 }
}
