<?php namespace Intellex\Pixabay\Validation;

use Intellex\Pixabay\Validation\ValidationException;

/**
 * Validator that helps validate elements of the object.
 * @class
 */
abstract class ClassMemberValidator {

	/**
	 * Validate a complete object.
	 *
	 * @param stdClass $object An object to validate.
	 * @param array $rules The list of rules to test against.
	 *
	 * @throws ValidationException On first invalid field.
	 */
	public static function validate($object, $rules) {

		# Iterate over each member
		foreach($rules as $member => $rules) {

			# There might be multiple rules
			$rules = (array) $rules;
			foreach($rules as $rule) {

				# Extract the parameters
				$params = '';
				if(strstr($rule, ':')) {
					list($rule, $params) = explode(':', $rule, 2);
				}

				# Test the value with the selected method
				$method = static::getMethod($rule);
				if($error = static::$method($object->$member, (array) explode(',', $params))) {
					throw new ValidationException(get_class($object), $member, $object->$member, $error);
				}
			}
		}
	}

	/**
	 * Get method for the supplied rule.
	 *
	 * @param string $name The name of the rule.
	 *
	 * @return string The name of the method to use, or null if method is not found.
	 */
	private static function getMethod($name) {
		$method = '_' . $name;
		return method_exists(get_called_class(), $method) ? $method : null;
	}

	public static function _required           ($val) { return is_null($val) || trim($val) === "" ? null : 'Value is required'; }
	public static function _notEmpty           ($val) { return !empty($val)                       ? null : 'Cannot be empty'; }
	public static function _notNull            ($val) { return !is_null($val)                     ? null : 'Cannot be null'; }
	public static function _notZero            ($val) { return $val !== 0 && !val !== "0"         ? null : 'Cannot be zero'; }

	public static function _integer            ($val) { return is_int($val)                         ? null : 'Must be an integer'; }
	public static function _positiveInteger    ($val) { return !static::_integer($val) && $val > 0  ? null : 'Must be a positive integer'; }
	public static function _nonNegativeInteger ($val) { return !static::_integer($val) && $val >= 0 ? null : 'Must be a non-negative integer'; }
	public static function _negativeInteger    ($val) { return !static::_integer($val) && $val < 0  ? null : 'Must be a negative integer'; }
	public static function _nonPositiveInteger ($val) { return !static::_integer($val) && $val <= 0 ? null : 'Must be a non-positive integer'; }

	public static function _string             ($val) { return is_string($val) ? null : 'Must be a string'; }
	public static function _nonEmptystring     ($val) { return _string($val) && !empty($val) ? null : 'Must be a non-empty string'; }

	public static function _array              ($val) { return is_array($val)                            ? null : 'Must be an array'; }
	public static function _nonEmptyArray      ($val) { return !static::_array($val) && sizeof($val) > 0 ? null : 'Must be a non-empty array'; }

}
