<?php

namespace LdapRecord\Models\Attributes;

use LdapRecord\EscapesValues;
use LdapRecord\Support\Arr;

class DistinguishedNameBuilder
{
    use EscapesValues;

    /**
     * The components of the DN.
     *
     * @var array
     */
    protected $components = [];

    /**
     * Whether to output the DN in reverse.
     *
     * @var bool
     */
    protected $reverse = false;

    /**
     * Constructor.
     *
     * @param string|null $value
     */
    public function __construct($dn = null)
    {
        $this->components = array_map(function ($rdn) {
            return DistinguishedName::explodeRdn($rdn);
        }, DistinguishedName::make($dn)->components());
    }

    /**
     * Forward missing method calls onto the Distinguished Name object.
     *
     * @param string $method
     * @param array  $args
     *
     * @return mixed
     */
    public function __call($method, $args)
    {
        return $this->get()->{$method}(...$args);
    }

    /**
     * Get the distinguished name value.
     *
     * @return string
     */
    public function __toString()
    {
        return (string) $this->get();
    }

    /**
     * Prepend an RDN onto the DN.
     *
     * @param string|array $attribute
     * @param string|null  $value
     *
     * @return $this
     */
    public function prepend($attribute, $value = null)
    {
        array_unshift(
            $this->components,
            ...$this->componentize($attribute, $value)
        );

        return $this;
    }

    /**
     * Append an RDN onto the DN.
     *
     * @param string|array $attribute
     * @param string|null  $value
     *
     * @return $this
     */
    public function append($attribute, $value = null)
    {
        array_push(
            $this->components,
            ...$this->componentize($attribute, $value)
        );

        return $this;
    }

    /**
     * Componentize the attribute and value.
     *
     * @param string|array $attribute
     * @param string|null  $value
     *
     * @return array
     */
    protected function componentize($attribute, $value = null)
    {
        // Here we will make the assumption that an array of
        // RDN's have been given if the value is null, and
        // attempt to break them into their components.
        if (is_null($value)) {
            $attributes = Arr::wrap($attribute);

            $components = array_map([$this, 'makeComponentizedArray'], $attributes);
        } else {
            $components = [[$attribute, $value]];
        }

        return array_map(function ($component) {
            [$attribute, $value] = $component;

            return $this->makeAppendableComponent($attribute, $value);
        }, $components);
    }

    /**
     * Make a componentized array by exploding the value if it's a string.
     *
     * @param string $value
     *
     * @return array
     */
    protected function makeComponentizedArray($value)
    {
        return is_array($value) ? $value : DistinguishedName::explodeRdn($value);
    }

    /**
     * Make an appendable component array from the attribute and value.
     *
     * @param string|array $attribute
     * @param string|null  $value
     *
     * @return array
     */
    protected function makeAppendableComponent($attribute, $value = null)
    {
        return [trim($attribute), $this->escape(trim($value))->dn()];
    }

    /**
     * Pop an RDN off of the end of the DN.
     *
     * @param int   $amount
     * @param array $removed
     *
     * @return $this
     */
    public function pop($amount = 1, &$removed = [])
    {
        $removed = array_map(function ($component) {
            return DistinguishedName::makeRdn($component);
        }, array_splice($this->components, -$amount, $amount));

        return $this;
    }

    /**
     * Shift an RDN off of the beginning of the DN.
     *
     * @param int   $amount
     * @param array $removed
     *
     * @return $this
     */
    public function shift($amount = 1, &$removed = [])
    {
        $removed = array_map(function ($component) {
            return DistinguishedName::makeRdn($component);
        }, array_splice($this->components, 0, $amount));

        return $this;
    }

    /**
     * Whether to output the DN in reverse.
     *
     * @return $this
     */
    public function reverse()
    {
        $this->reverse = true;

        return $this;
    }

    /**
     * Get the components of the DN.
     *
     * @param null|string $type
     *
     * @return array
     */
    public function components($type = null)
    {
        return is_null($type)
            ? $this->components
            : $this->componentsOfType($type);
    }

    /**
     * Get the components of a particular type.
     *
     * @param string $type
     *
     * @return array
     */
    protected function componentsOfType($type)
    {
        $components = array_filter($this->components, function ($component) use ($type) {
            return ([$name] = $component) && strtolower($name) === strtolower($type);
        });

        return array_values($components);
    }

    /**
     * Get the fully qualified DN.
     *
     * @return DistinguishedName
     */
    public function get()
    {
        return new DistinguishedName($this->build());
    }

    /**
     * Build the distinguished name from the components.
     *
     * @return $this
     */
    protected function build()
    {
        $components = $this->reverse
            ? array_reverse($this->components)
            : $this->components;

        return implode(',', array_map(function ($component) {
            return DistinguishedName::makeRdn($component);
        }, $components));
    }
}
