<?php

namespace LdapRecord\Models\Concerns;

use LdapRecord\ConnectionException;
use LdapRecord\LdapRecordException;
use LdapRecord\Models\Attributes\Password;

trait HasPassword
{
    /**
     * Set the password on the user.
     *
     * @param string|array $password
     *
     * @throws ConnectionException
     */
    public function setPasswordAttribute($password)
    {
        $this->validateSecureConnection();

        // Here we will attempt to determine the password hash method in use
        // by parsing the users hashed password (if it as available). If a
        // method is determined, we will override the default here.
        if (! ($method = $this->determinePasswordHashMethod())) {
            $method = $this->getPasswordHashMethod();
        }

        // If the password given is an array, we can assume we
        // are changing the password for the current user.
        if (is_array($password)) {
            $this->setChangedPassword(
                $this->getHashedPassword($method, $password[0], $this->getPasswordSalt($method)),
                $this->getHashedPassword($method, $password[1]),
                $this->getPasswordAttributeName()
            );
        }
        // Otherwise, we will assume the password is being
        // reset, overwriting the one currently in place.
        else {
            $this->setPassword(
                $this->getHashedPassword($method, $password),
                $this->getPasswordAttributeName()
            );
        }
    }

    /**
     * Alias for setting the password on the user.
     *
     * @param string|array $password
     *
     * @throws ConnectionException
     */
    public function setUnicodepwdAttribute($password)
    {
        $this->setPasswordAttribute($password);
    }

    /**
     * An accessor for retrieving the user's hashed password value.
     *
     * @return string|null
     */
    public function getPasswordAttribute()
    {
        return $this->getAttribute($this->getPasswordAttributeName())[0] ?? null;
    }

    /**
     * Get the name of the attribute that contains the user's password.
     *
     * @return string
     */
    public function getPasswordAttributeName()
    {
        if (property_exists($this, 'passwordAttribute')) {
            return $this->passwordAttribute;
        }

        if (method_exists($this, 'passwordAttribute')) {
            return $this->passwordAttribute();
        }

        return 'unicodepwd';
    }

    /**
     * Get the name of the method to use for hashing the user's password.
     *
     * @return string
     */
    public function getPasswordHashMethod()
    {
        if (property_exists($this, 'passwordHashMethod')) {
            return $this->passwordHashMethod;
        }

        if (method_exists($this, 'passwordHashMethod')) {
            return $this->passwordHashMethod();
        }

        return 'encode';
    }

    /**
     * Set the changed password.
     *
     * @param string $oldPassword
     * @param string $newPassword
     * @param string $attribute
     *
     * @return void
     */
    protected function setChangedPassword($oldPassword, $newPassword, $attribute)
    {
        // Create batch modification for removing the old password.
        $this->addModification(
            $this->newBatchModification(
                $attribute,
                LDAP_MODIFY_BATCH_REMOVE,
                [$oldPassword]
            )
        );

        // Create batch modification for adding the new password.
        $this->addModification(
            $this->newBatchModification(
                $attribute,
                LDAP_MODIFY_BATCH_ADD,
                [$newPassword]
            )
        );
    }

    /**
     * Set the password on the model.
     *
     * @param string $password
     * @param string $attribute
     *
     * @return void
     */
    protected function setPassword($password, $attribute)
    {
        $this->addModification(
            $this->newBatchModification(
                $attribute,
                LDAP_MODIFY_BATCH_REPLACE,
                [$password]
            )
        );
    }

    /**
     * Encode / hash the given password.
     *
     * @param string $method
     * @param string $password
     * @param string $salt
     *
     * @throws LdapRecordException
     *
     * @return string
     */
    protected function getHashedPassword($method, $password, $salt = null)
    {
        if (! method_exists(Password::class, $method)) {
            throw new LdapRecordException("Password hashing method [{$method}] does not exist.");
        }

        if (Password::hashMethodRequiresSalt($method)) {
            return Password::{$method}($password, $salt);
        }

        return Password::{$method}($password);
    }

    /**
     * Validates that the current LDAP connection is secure.
     *
     * @throws ConnectionException
     *
     * @return void
     */
    protected function validateSecureConnection()
    {
        $connection = $this->getConnection();

        if ($connection->isConnected()) {
            $secure = $connection->getLdapConnection()->canChangePasswords();
        } else {
            $secure = $connection->getConfiguration()->get('use_ssl') || $connection->getConfiguration()->get('use_tls');
        }

        if (! $secure) {
            throw new ConnectionException(
                'You must be connected to your LDAP server with TLS or SSL to perform this operation.'
            );
        }
    }

    /**
     * Attempt to retrieve the password's salt.
     *
     * @param string $method
     *
     * @return string|null
     */
    public function getPasswordSalt($method)
    {
        if (! Password::hashMethodRequiresSalt($method)) {
            return;
        }

        return Password::getSalt($this->password);
    }

    /**
     * Determine the password hash method to use from the users current password.
     *
     * @return string|void
     */
    public function determinePasswordHashMethod()
    {
        if (! $password = $this->password) {
            return;
        }

        if (! $method = Password::getHashMethod($password)) {
            return;
        }

        [,$algo] = array_pad(
            Password::getHashMethodAndAlgo($password) ?? [],
            $length = 2,
            $value = null
        );

        switch ($algo) {
            case Password::CRYPT_SALT_TYPE_MD5:
                return 'md5'.$method;
            case Password::CRYPT_SALT_TYPE_SHA256:
                return 'sha256'.$method;
            case Password::CRYPT_SALT_TYPE_SHA512:
                return 'sha512'.$method;
            default:
                return $method;
        }
    }
}
