<?php

namespace LdapRecord\Models;

use InvalidArgumentException;

class BatchModification
{
    use DetectsResetIntegers;

    /**
     * The array keys to be used in batch modifications.
     */
    const KEY_ATTRIB = 'attrib';
    const KEY_MODTYPE = 'modtype';
    const KEY_VALUES = 'values';

    /**
     * The attribute of the modification.
     *
     * @var string|null
     */
    protected $attribute;

    /**
     * The original value of the attribute before modification.
     *
     * @var array
     */
    protected $original = [];

    /**
     * The values of the modification.
     *
     * @var array
     */
    protected $values = [];

    /**
     * The modtype integer of the batch modification.
     *
     * @var int|null
     */
    protected $type;

    /**
     * Constructor.
     *
     * @param string|null     $attribute
     * @param string|int|null $type
     * @param array           $values
     */
    public function __construct($attribute = null, $type = null, array $values = [])
    {
        $this->setAttribute($attribute)
            ->setType($type)
            ->setValues($values);
    }

    /**
     * Set the original value of the attribute before modification.
     *
     * @param array|string $original
     *
     * @return $this
     */
    public function setOriginal($original = [])
    {
        $this->original = $this->normalizeAttributeValues($original);

        return $this;
    }

    /**
     * Returns the original value of the attribute before modification.
     *
     * @return array
     */
    public function getOriginal()
    {
        return $this->original;
    }

    /**
     * Set the attribute of the modification.
     *
     * @param string $attribute
     *
     * @return $this
     */
    public function setAttribute($attribute)
    {
        $this->attribute = $attribute;

        return $this;
    }

    /**
     * Returns the attribute of the modification.
     *
     * @return string
     */
    public function getAttribute()
    {
        return $this->attribute;
    }

    /**
     * Set the values of the modification.
     *
     * @param array $values
     *
     * @return $this
     */
    public function setValues(array $values = [])
    {
        // Null and empty values must also not be added to a batch
        // modification. Passing null or empty values will result
        // in an exception when trying to save the modification.
        $this->values = array_filter($this->normalizeAttributeValues($values), function ($value) {
            return is_numeric($value) && $this->valueIsResetInteger((int) $value) ?: ! empty($value);
        });

        return $this;
    }

    /**
     * Normalize all of the attribute values.
     *
     * @param array|string $values
     *
     * @return array
     */
    protected function normalizeAttributeValues($values = [])
    {
        // We must convert all of the values to strings. Only strings can
        // be used in batch modifications, otherwise we will we will
        // receive an LDAP exception while attempting to save.
        return array_map('strval', (array) $values);
    }

    /**
     * Returns the values of the modification.
     *
     * @return array
     */
    public function getValues()
    {
        return $this->values;
    }

    /**
     * Set the type of the modification.
     *
     * @param int|null $type
     *
     * @return $this
     */
    public function setType($type = null)
    {
        if (is_null($type)) {
            return $this;
        }

        if (! $this->isValidType($type)) {
            throw new InvalidArgumentException('Given batch modification type is invalid.');
        }

        $this->type = $type;

        return $this;
    }

    /**
     * Returns the type of the modification.
     *
     * @return int
     */
    public function getType()
    {
        return $this->type;
    }

    /**
     * Determines if the batch modification is valid in its current state.
     *
     * @return bool
     */
    public function isValid()
    {
        return ! is_null($this->get());
    }

    /**
     * Builds the type of modification automatically
     * based on the current and original values.
     *
     * @return $this
     */
    public function build()
    {
        switch (true) {
            case empty($this->original) && empty($this->values):
                return $this;
            case ! empty($this->original) && empty($this->values):
                return $this->setType(LDAP_MODIFY_BATCH_REMOVE_ALL);
            case empty($this->original) && ! empty($this->values):
                return $this->setType(LDAP_MODIFY_BATCH_ADD);
            default:
               return $this->determineBatchTypeFromOriginal();
        }
    }

    /**
     * Determine the batch modification type from the original values.
     *
     * @return $this
     */
    protected function determineBatchTypeFromOriginal()
    {
        $added = $this->getAddedValues();
        $removed = $this->getRemovedValues();

        switch (true) {
            case ! empty($added) && ! empty($removed):
                return $this->setType(LDAP_MODIFY_BATCH_REPLACE);
            case ! empty($added):
                return $this->setValues($added)->setType(LDAP_MODIFY_BATCH_ADD);
            case ! empty($removed):
                return $this->setValues($removed)->setType(LDAP_MODIFY_BATCH_REMOVE);
            default:
                return $this;
        }
    }

    /**
     * Get the values that were added to the attribute.
     *
     * @return array
     */
    protected function getAddedValues()
    {
        return array_values(
            array_diff($this->values, $this->original)
        );
    }

    /**
     * Get the values that were removed from the attribute.
     *
     * @return array
     */
    protected function getRemovedValues()
    {
        return array_values(
            array_diff($this->original, $this->values)
        );
    }

    /**
     * Returns the built batch modification array.
     *
     * @return array|null
     */
    public function get()
    {
        switch ($this->type) {
            case LDAP_MODIFY_BATCH_REMOVE_ALL:
                // A values key cannot be provided when
                // a remove all type is selected.
                return [
                    static::KEY_ATTRIB => $this->attribute,
                    static::KEY_MODTYPE => $this->type,
                ];
            case LDAP_MODIFY_BATCH_REMOVE:
                // Fallthrough.
            case LDAP_MODIFY_BATCH_ADD:
                // Fallthrough.
            case LDAP_MODIFY_BATCH_REPLACE:
                return [
                    static::KEY_ATTRIB => $this->attribute,
                    static::KEY_MODTYPE => $this->type,
                    static::KEY_VALUES => $this->values,
                ];
            default:
                // If the modtype isn't recognized, we'll return null.
                return;
        }
    }

    /**
     * Determines if the given modtype is valid.
     *
     * @param int $type
     *
     * @return bool
     */
    protected function isValidType($type)
    {
        return in_array($type, [
            LDAP_MODIFY_BATCH_REMOVE_ALL,
            LDAP_MODIFY_BATCH_REMOVE,
            LDAP_MODIFY_BATCH_REPLACE,
            LDAP_MODIFY_BATCH_ADD,
        ]);
    }
}
