<?php

namespace LdapRecord\Testing;

use Exception;
use LdapRecord\DetailedError;
use LdapRecord\DetectsErrors;
use LdapRecord\HandlesConnection;
use LdapRecord\LdapInterface;
use LdapRecord\Support\Arr;
use PHPUnit\Framework\Assert as PHPUnit;
use PHPUnit\Framework\Constraint\Constraint;

class LdapFake implements LdapInterface
{
    use HandlesConnection, DetectsErrors;

    /**
     * The expectations of the LDAP fake.
     *
     * @var array
     */
    protected $expectations = [];

    /**
     * The default fake error number.
     *
     * @var int
     */
    protected $errNo = 1;

    /**
     * The default fake last error string.
     *
     * @var string
     */
    protected $lastError = '';

    /**
     * The default fake diagnostic message string.
     *
     * @var string
     */
    protected $diagnosticMessage = '';

    /**
     * Create a new expected operation.
     *
     * @param string $method
     *
     * @return LdapExpectation
     */
    public static function operation($method)
    {
        return new LdapExpectation($method);
    }

    /**
     * Set the user that will pass binding.
     *
     * @param string $dn
     *
     * @return $this
     */
    public function shouldAuthenticateWith($dn)
    {
        return $this->expect(
            static::operation('bind')->with($dn, PHPUnit::anything())->andReturn(true)
        );
    }

    /**
     * Add an LDAP method expectation.
     *
     * @param LdapExpectation|array $expectations
     *
     * @return $this
     */
    public function expect($expectations = [])
    {
        $expectations = Arr::wrap($expectations);

        foreach ($expectations as $key => $expectation) {
            // If the key is non-numeric, we will assume
            // that the string is the method name and
            // the expectation is the return value.
            if (! is_numeric($key)) {
                $expectation = static::operation($key)->andReturn($expectation);
            }

            if (! $expectation instanceof LdapExpectation) {
                $expectation = static::operation($expectation);
            }

            $this->expectations[$expectation->getMethod()][] = $expectation;
        }

        return $this;
    }

    /**
     * Determine if the method has any expectations.
     *
     * @param string $method
     *
     * @return bool
     */
    public function hasExpectations($method)
    {
        return count($this->getExpectations($method)) > 0;
    }

    /**
     * Get expectations by method.
     *
     * @param string $method
     *
     * @return LdapExpectation[]|mixed
     */
    public function getExpectations($method)
    {
        return $this->expectations[$method] ?? [];
    }

    /**
     * Remove an expectation by method and key.
     *
     * @param string $method
     * @param int    $key
     *
     * @return void
     */
    public function removeExpectation($method, $key)
    {
        unset($this->expectations[$method][$key]);
    }

    /**
     * Set the error number of a failed bind attempt.
     *
     * @param int $number
     *
     * @return $this
     */
    public function shouldReturnErrorNumber($number = 1)
    {
        $this->errNo = $number;

        return $this;
    }

    /**
     * Set the last error of a failed bind attempt.
     *
     * @param string $message
     *
     * @return $this
     */
    public function shouldReturnError($message = '')
    {
        $this->lastError = $message;

        return $this;
    }

    /**
     * Set the diagnostic message of a failed bind attempt.
     *
     * @param string $message
     *
     * @return $this
     */
    public function shouldReturnDiagnosticMessage($message = '')
    {
        $this->diagnosticMessage = $message;

        return $this;
    }

    /**
     * Return a fake error number.
     *
     * @return int
     */
    public function errNo()
    {
        return $this->errNo;
    }

    /**
     * Return a fake error.
     *
     * @return string
     */
    public function getLastError()
    {
        return $this->lastError;
    }

    /**
     * @inheritdoc
     */
    public function getDiagnosticMessage()
    {
        return $this->diagnosticMessage;
    }

    /**
     * Return a fake detailed error.
     *
     * @return DetailedError
     */
    public function getDetailedError()
    {
        return new DetailedError(
            $this->errNo(),
            $this->getLastError(),
            $this->getDiagnosticMessage()
        );
    }

    /**
     * @inheritdoc
     */
    public function getEntries($searchResults)
    {
        return $searchResults;
    }

    /**
     * @inheritdoc
     */
    public function isUsingSSL()
    {
        return $this->hasExpectations('isUsingSSL')
            ? $this->resolveExpectation('isUsingSSL')
            : $this->useSSL;
    }

    /**
     * @inheritdoc
     */
    public function isUsingTLS()
    {
        return $this->hasExpectations('isUsingTLS')
            ? $this->resolveExpectation('isUsingTLS')
            : $this->useTLS;
    }

    /**
     * @inheritdoc
     */
    public function isBound()
    {
        return $this->hasExpectations('isBound')
            ? $this->resolveExpectation('isBound')
            : $this->bound;
    }

    /**
     * @inheritdoc
     */
    public function setOption($option, $value)
    {
        return $this->hasExpectations('setOption')
            ? $this->resolveExpectation('setOption', func_get_args())
            : true;
    }

    /**
     * @inheritdoc
     */
    public function getOption($option, &$value = null)
    {
        return $this->resolveExpectation('getOption', func_get_args());
    }

    /**
     * @inheritdoc
     */
    public function startTLS()
    {
        return $this->resolveExpectation('startTLS', func_get_args());
    }

    /**
     * @inheritdoc
     */
    public function connect($hosts = [], $port = 389)
    {
        $this->bound = false;

        $this->host = $this->makeConnectionUris($hosts, $port);

        return $this->connection = $this->hasExpectations('connect')
            ? $this->resolveExpectation('connect', func_get_args())
            : true;
    }

    /**
     * @inheritdoc
     */
    public function close()
    {
        $this->connection = null;
        $this->bound = false;
        $this->host = null;

        return $this->hasExpectations('close')
            ? $this->resolveExpectation('close')
            : true;
    }

    /**
     * @inheritdoc
     */
    public function bind($username, $password)
    {
        return $this->bound = $this->resolveExpectation('bind', func_get_args());
    }

    /**
     * @inheritdoc
     */
    public function search($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = null, $serverControls = [])
    {
        return $this->resolveExpectation('search', func_get_args());
    }

    /**
     * @inheritdoc
     */
    public function listing($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = null, $serverControls = [])
    {
        return $this->resolveExpectation('listing', func_get_args());
    }

    /**
     * @inheritdoc
     */
    public function read($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = null, $serverControls = [])
    {
        return $this->resolveExpectation('read', func_get_args());
    }

    /**
     * @inheritdoc
     */
    public function parseResult($result, &$errorCode, &$dn, &$errorMessage, &$referrals, &$serverControls = [])
    {
        return $this->resolveExpectation('parseResult', func_get_args());
    }

    /**
     * @inheritdoc
     */
    public function add($dn, array $entry)
    {
        return $this->resolveExpectation('add', func_get_args());
    }

    /**
     * @inheritdoc
     */
    public function delete($dn)
    {
        return $this->resolveExpectation('delete', func_get_args());
    }

    /**
     * @inheritdoc
     */
    public function rename($dn, $newRdn, $newParent, $deleteOldRdn = false)
    {
        return $this->resolveExpectation('rename', func_get_args());
    }

    /**
     * @inheritdoc
     */
    public function modify($dn, array $entry)
    {
        return $this->resolveExpectation('modify', func_get_args());
    }

    /**
     * @inheritdoc
     */
    public function modifyBatch($dn, array $values)
    {
        return $this->resolveExpectation('modifyBatch', func_get_args());
    }

    /**
     * @inheritdoc
     */
    public function modAdd($dn, array $entry)
    {
        return $this->resolveExpectation('modAdd', func_get_args());
    }

    /**
     * @inheritdoc
     */
    public function modReplace($dn, array $entry)
    {
        return $this->resolveExpectation('modReplace', func_get_args());
    }

    /**
     * @inheritdoc
     */
    public function modDelete($dn, array $entry)
    {
        return $this->resolveExpectation('modDelete', func_get_args());
    }

    /**
     * @inheritdoc
     */
    public function controlPagedResult($pageSize = 1000, $isCritical = false, $cookie = '')
    {
        return $this->resolveExpectation('controlPagedResult', func_get_args());
    }

    /**
     * @inheritdoc
     */
    public function controlPagedResultResponse($result, &$cookie)
    {
        return $this->resolveExpectation('controlPagedResultResponse', func_get_args());
    }

    /**
     * @inheritdoc
     */
    public function freeResult($result)
    {
        return $this->resolveExpectation('freeResult', func_get_args());
    }

    /**
     * @inheritdoc
     */
    public function err2Str($number)
    {
        return $this->resolveExpectation('err2Str', func_get_args());
    }

    /**
     * Resolve the methods expectations.
     *
     * @param string $method
     * @param array  $args
     *
     * @throws Exception
     *
     * @return mixed
     */
    protected function resolveExpectation($method, array $args = [])
    {
        foreach ($this->getExpectations($method) as $key => $expectation) {
            $this->assertMethodArgumentsMatch($method, $expectation->getExpectedArgs(), $args);

            $expectation->decrementCallCount();

            if ($expectation->getExpectedCount() === 0) {
                $this->removeExpectation($method, $key);
            }

            if (! is_null($exception = $expectation->getExpectedException())) {
                throw $exception;
            }

            if ($expectation->isReturningError()) {
                $this->applyExpectationError($expectation);
            }

            return $expectation->getExpectedValue();
        }

        throw new Exception("LDAP method [$method] was unexpected.");
    }

    /**
     * Apply the expectation error to the fake.
     *
     * @param LdapExpectation $expectation
     *
     * @return void
     */
    protected function applyExpectationError(LdapExpectation $expectation)
    {
        $this->shouldReturnError($expectation->getExpectedErrorMessage());
        $this->shouldReturnErrorNumber($expectation->getExpectedErrorCode());
        $this->shouldReturnDiagnosticMessage($expectation->getExpectedErrorDiagnosticMessage());
    }

    /**
     * Assert that the expected arguments match the operations arguments.
     *
     * @param string       $method
     * @param Constraint[] $expectedArgs
     * @param array        $methodArgs
     *
     * @return void
     */
    protected function assertMethodArgumentsMatch($method, array $expectedArgs = [], array $methodArgs = [])
    {
        foreach ($expectedArgs as $key => $constraint) {
            $argNumber = $key + 1;

            PHPUnit::assertArrayHasKey(
                $key,
                $methodArgs,
                "LDAP method [$method] argument #{$argNumber} does not exist."
            );

            $constraint->evaluate(
                $methodArgs[$key],
                "LDAP method [$method] expectation failed."
            );
        }
    }
}
