<?php

namespace idoit\Module\Forms\Model\Validators;

use isys_cmdb_dao_category;
use ReflectionClass;

class CategoryValidator implements ValidatorInterface
{
  /**
   * @var ValidatorInterface
   */
  private $validator;

  /**
   * @var ValidatorInterface[]
   */
  private $validators = [];

  /**
   * @return CategoryValidator
   */
  public static function factory()
  {
    $instance = new self();
    $instance->loadCategoryValidators();

    return $instance;
  }

  /**
   * @param string $categoryConst
   *
   * @return bool
   */
  public function isApplicable(string $categoryConst): bool
  {
    foreach ($this->validators as $validator) {
      if ($validator->isApplicable($categoryConst)) {
        $this->validator = $validator;
        return true;
      }
    }

    return false;
  }

  /**
   * @param array                  $formData
   * @param isys_cmdb_dao_category $categoryDao
   *
   * @return array|null
   */
  public function validate(array $formData, isys_cmdb_dao_category $categoryDao): ?array
  {
    return $this->validator->validate($formData, $categoryDao);
  }

  /**
   * @return void
   */
  public function loadCategoryValidators()
  {
    $validatorsDirectory = __DIR__ . '/Category/';
    $validatorBaseNameSpace = 'idoit\\Module\\Forms\\Model\\Validators';
    $handle = opendir($validatorsDirectory);

    while (false !== ($file = readdir($handle))) {
      if ($file === '.' || $file === '..') {
        continue;
      }
      $class = $validatorBaseNameSpace . '\\Category\\' .substr($file, 0, strpos($file, '.'));

      if (class_exists($class)) {
        $reflection = new ReflectionClass($class);
        if ($reflection->isSubclassOf($validatorBaseNameSpace . '\\ValidatorInterface')) {
          $this->validators[] = call_user_func([$class, 'factory']);
        }
      }
    }
  }
}
