<?php

namespace LdapRecord\Models\Relations;

use LdapRecord\Models\Model;
use LdapRecord\Query\Collection;
use LdapRecord\Query\Model\Builder;

abstract class OneToMany extends Relation
{
    /**
     * The relation to merge results with.
     *
     * @var OneToMany|null
     */
    protected $with;

    /**
     * The name of the relationship.
     *
     * @var string
     */
    protected $relationName;

    /**
     * Whether to include recursive results.
     *
     * @var bool
     */
    protected $recursive = false;

    /**
     * Constructor.
     *
     * @param Builder $query
     * @param Model   $parent
     * @param string  $related
     * @param string  $relationKey
     * @param string  $foreignKey
     * @param string  $relationName
     */
    public function __construct(Builder $query, Model $parent, $related, $relationKey, $foreignKey, $relationName)
    {
        $this->relationName = $relationName;

        parent::__construct($query, $parent, $related, $relationKey, $foreignKey);
    }

    /**
     * Set the relation to load with its parent.
     *
     * @param OneToMany $relation
     *
     * @return $this
     */
    public function with(Relation $relation)
    {
        $this->with = $relation;

        return $this;
    }

    /**
     * Whether to include recursive results.
     *
     * @param bool $enable
     *
     * @return $this
     */
    public function recursive($enable = true)
    {
        $this->recursive = $enable;

        return $this;
    }

    /**
     * Get the immediate relationships results.
     *
     * @return Collection
     */
    abstract public function getRelationResults();

    /**
     * Get the results of the relationship.
     *
     * @return Collection
     */
    public function getResults()
    {
        $results = $this->recursive
            ? $this->getRecursiveResults()
            : $this->getRelationResults();

        return $results->merge(
            $this->getMergingRelationResults()
        );
    }

    /**
     * Execute the callback excluding the merged query result.
     *
     * @param callable $callback
     *
     * @return mixed
     */
    protected function onceWithoutMerging($callback)
    {
        $merging = $this->with;

        $this->with = null;

        $result = $callback();

        $this->with = $merging;

        return $result;
    }

    /**
     * Get the relation name.
     *
     * @return string
     */
    public function getRelationName()
    {
        return $this->relationName;
    }

    /**
     * Get the results of the merging 'with' relation.
     *
     * @return Collection
     */
    protected function getMergingRelationResults()
    {
        return $this->with
            ? $this->with->recursive($this->recursive)->get()
            : $this->parent->newCollection();
    }

    /**
     * Get the results for the models relation recursively.
     *
     * @param string[] $loaded The distinguished names of models already loaded
     *
     * @return Collection
     */
    protected function getRecursiveResults(array $loaded = [])
    {
        $results = $this->getRelationResults()->reject(function (Model $model) use ($loaded) {
            // Here we will exclude the models that we have already
            // loaded the recursive results for so we don't run
            // into issues with circular relations in LDAP.
            return in_array($model->getDn(), $loaded);
        });

        foreach ($results as $model) {
            $loaded[] = $model->getDn();

            // Finally, we will fetch the related models relations,
            // passing along our loaded models, to ensure we do
            // not attempt fetching already loaded relations.
            $results = $results->merge(
                $this->getRecursiveRelationResults($model, $loaded)
            );
        }

        return $results;
    }

    /**
     * Get the recursive relation results for given model.
     *
     * @param Model $model
     * @param array $loaded
     *
     * @return Collection
     */
    protected function getRecursiveRelationResults(Model $model, array $loaded)
    {
        return method_exists($model, $this->relationName)
            ? $model->{$this->relationName}()->getRecursiveResults($loaded)
            : $model->newCollection();
    }
}
