<?php

namespace LdapRecord\Models\Attributes;

use ReflectionClass;

class AccountControl
{
    const SCRIPT = 1;

    const ACCOUNTDISABLE = 2;

    const HOMEDIR_REQUIRED = 8;

    const LOCKOUT = 16;

    const PASSWD_NOTREQD = 32;

    const PASSWD_CANT_CHANGE = 64;

    const ENCRYPTED_TEXT_PWD_ALLOWED = 128;

    const TEMP_DUPLICATE_ACCOUNT = 256;

    const NORMAL_ACCOUNT = 512;

    const INTERDOMAIN_TRUST_ACCOUNT = 2048;

    const WORKSTATION_TRUST_ACCOUNT = 4096;

    const SERVER_TRUST_ACCOUNT = 8192;

    const DONT_EXPIRE_PASSWORD = 65536;

    const MNS_LOGON_ACCOUNT = 131072;

    const SMARTCARD_REQUIRED = 262144;

    const TRUSTED_FOR_DELEGATION = 524288;

    const NOT_DELEGATED = 1048576;

    const USE_DES_KEY_ONLY = 2097152;

    const DONT_REQ_PREAUTH = 4194304;

    const PASSWORD_EXPIRED = 8388608;

    const TRUSTED_TO_AUTH_FOR_DELEGATION = 16777216;

    const PARTIAL_SECRETS_ACCOUNT = 67108864;

    /**
     * The account control flag values.
     *
     * @var array<int, int>
     */
    protected $values = [];

    /**
     * Constructor.
     *
     * @param ?int $flag
     */
    public function __construct($flag = null)
    {
        if (! is_null($flag)) {
            $this->apply($flag);
        }
    }

    /**
     * Get the value when casted to string.
     *
     * @return string
     */
    public function __toString()
    {
        return (string) $this->getValue();
    }

    /**
     * Get the value when casted to int.
     *
     * @return int
     */
    public function __toInt()
    {
        return $this->getValue();
    }

    /**
     * Add the flag to the account control values.
     *
     * @param int $flag
     *
     * @return $this
     */
    public function add($flag)
    {
        // Use the value as a key so if the same value
        // is used, it will always be overwritten
        $this->values[$flag] = $flag;

        return $this;
    }

    /**
     * Remove the flag from the account control.
     *
     * @param int $flag
     *
     * @return $this
     */
    public function remove($flag)
    {
        unset($this->values[$flag]);

        return $this;
    }

    /**
     * Extract and apply the flag.
     *
     * @param int $flag
     *
     * @return void
     */
    public function apply($flag)
    {
        $this->setValues($this->extractFlags($flag));
    }

    /**
     * Determine if the account control contains the given UAC flag(s).
     *
     * @param int $flag
     *
     * @return bool
     */
    public function has($flag)
    {
        // Here we will extract the given flag into an array
        // of possible flags. This will allow us to see if
        // our AccountControl object contains any of them.
        $flagsUsed = array_intersect(
            $this->extractFlags($flag),
            $this->values
        );

        return in_array($flag, $flagsUsed);
    }

    /**
     * Determine if the account control does not contain the given UAC flag(s).
     *
     * @param int $flag
     *
     * @return bool
     */
    public function doesntHave($flag)
    {
        return ! $this->has($flag);
    }

    /**
     * Generate an LDAP filter based on the current value.
     *
     * @return string
     */
    public function filter()
    {
        return sprintf('(UserAccountControl:1.2.840.113556.1.4.803:=%s)', $this->getValue());
    }

    /**
     * The logon script will be run.
     *
     * @return $this
     */
    public function runLoginScript()
    {
        return $this->add(static::SCRIPT);
    }

    /**
     * The user account is locked.
     *
     * @return $this
     */
    public function accountIsLocked()
    {
        return $this->add(static::LOCKOUT);
    }

    /**
     * The user account is disabled.
     *
     * @return $this
     */
    public function accountIsDisabled()
    {
        return $this->add(static::ACCOUNTDISABLE);
    }

    /**
     * This is an account for users whose primary account is in another domain.
     *
     * This account provides user access to this domain, but not to any domain that
     * trusts this domain. This is sometimes referred to as a local user account.
     *
     * @return $this
     */
    public function accountIsTemporary()
    {
        return $this->add(static::TEMP_DUPLICATE_ACCOUNT);
    }

    /**
     * This is a default account type that represents a typical user.
     *
     * @return $this
     */
    public function accountIsNormal()
    {
        return $this->add(static::NORMAL_ACCOUNT);
    }

    /**
     * This is a permit to trust an account for a system domain that trusts other domains.
     *
     * @return $this
     */
    public function accountIsForInterdomain()
    {
        return $this->add(static::INTERDOMAIN_TRUST_ACCOUNT);
    }

    /**
     * This is a computer account for a computer that is running Microsoft
     * Windows NT 4.0 Workstation, Microsoft Windows NT 4.0 Server, Microsoft
     * Windows 2000 Professional, or Windows 2000 Server and is a member of this domain.
     *
     * @return $this
     */
    public function accountIsForWorkstation()
    {
        return $this->add(static::WORKSTATION_TRUST_ACCOUNT);
    }

    /**
     * This is a computer account for a domain controller that is a member of this domain.
     *
     * @return $this
     */
    public function accountIsForServer()
    {
        return $this->add(static::SERVER_TRUST_ACCOUNT);
    }

    /**
     * This is an MNS logon account.
     *
     * @return $this
     */
    public function accountIsMnsLogon()
    {
        return $this->add(static::MNS_LOGON_ACCOUNT);
    }

    /**
     * (Windows 2000/Windows Server 2003) This account does
     * not require Kerberos pre-authentication for logging on.
     *
     * @return $this
     */
    public function accountDoesNotRequirePreAuth()
    {
        return $this->add(static::DONT_REQ_PREAUTH);
    }

    /**
     * When this flag is set, it forces the user to log on by using a smart card.
     *
     * @return $this
     */
    public function accountRequiresSmartCard()
    {
        return $this->add(static::SMARTCARD_REQUIRED);
    }

    /**
     * (Windows Server 2008/Windows Server 2008 R2) The account is a read-only domain controller (RODC).
     *
     * This is a security-sensitive setting. Removing this setting from an RODC compromises security on that server.
     *
     * @return $this
     */
    public function accountIsReadOnly()
    {
        return $this->add(static::PARTIAL_SECRETS_ACCOUNT);
    }

    /**
     * The home folder is required.
     *
     * @return $this
     */
    public function homeFolderIsRequired()
    {
        return $this->add(static::HOMEDIR_REQUIRED);
    }

    /**
     * No password is required.
     *
     * @return $this
     */
    public function passwordIsNotRequired()
    {
        return $this->add(static::PASSWD_NOTREQD);
    }

    /**
     * The user cannot change the password. This is a permission on the user's object.
     *
     * For information about how to programmatically set this permission, visit the following link:
     *
     * @see http://msdn2.microsoft.com/en-us/library/aa746398.aspx
     *
     * @return $this
     */
    public function passwordCannotBeChanged()
    {
        return $this->add(static::PASSWD_CANT_CHANGE);
    }

    /**
     * Represents the password, which should never expire on the account.
     *
     * @return $this
     */
    public function passwordDoesNotExpire()
    {
        return $this->add(static::DONT_EXPIRE_PASSWORD);
    }

    /**
     * (Windows 2000/Windows Server 2003) The user's password has expired.
     *
     * @return $this
     */
    public function passwordIsExpired()
    {
        return $this->add(static::PASSWORD_EXPIRED);
    }

    /**
     * The user can send an encrypted password.
     *
     * @return $this
     */
    public function allowEncryptedTextPassword()
    {
        return $this->add(static::ENCRYPTED_TEXT_PWD_ALLOWED);
    }

    /**
     * When this flag is set, the service account (the user or computer account)
     * under which a service runs is trusted for Kerberos delegation.
     *
     * Any such service can impersonate a client requesting the service.
     *
     * To enable a service for Kerberos delegation, you must set this
     * flag on the userAccountControl property of the service account.
     *
     * @return $this
     */
    public function trustForDelegation()
    {
        return $this->add(static::TRUSTED_FOR_DELEGATION);
    }

    /**
     * (Windows 2000/Windows Server 2003) The account is enabled for delegation.
     *
     * This is a security-sensitive setting. Accounts that have this option enabled
     * should be tightly controlled. This setting lets a service that runs under the
     * account assume a client's identity and authenticate as that user to other remote
     * servers on the network.
     *
     * @return $this
     */
    public function trustToAuthForDelegation()
    {
        return $this->add(static::TRUSTED_TO_AUTH_FOR_DELEGATION);
    }

    /**
     * When this flag is set, the security context of the user is not delegated to a
     * service even if the service account is set as trusted for Kerberos delegation.
     *
     * @return $this
     */
    public function doNotTrustForDelegation()
    {
        return $this->add(static::NOT_DELEGATED);
    }

    /**
     * (Windows 2000/Windows Server 2003) Restrict this principal to
     * use only Data Encryption Standard (DES) encryption types for keys.
     *
     * @return $this
     */
    public function useDesKeyOnly()
    {
        return $this->add(static::USE_DES_KEY_ONLY);
    }

    /**
     * Get the account control value.
     *
     * @return int
     */
    public function getValue()
    {
        return array_sum($this->values);
    }

    /**
     * Get the account control flag values.
     *
     * @return array<int, int>
     */
    public function getValues()
    {
        return $this->values;
    }

    /**
     * Set the account control values.
     *
     * @param array<int, int> $flags
     *
     * @return void
     */
    public function setValues(array $flags)
    {
        $this->values = $flags;
    }

    /**
     * Get all flags that are currently applied to the value.
     *
     * @return array
     */
    public function getAppliedFlags()
    {
        $flags = $this->getAllFlags();

        $exists = [];

        foreach ($flags as $name => $flag) {
            if ($this->has($flag)) {
                $exists[$name] = $flag;
            }
        }

        return $exists;
    }

    /**
     * Get all possible account control flags.
     *
     * @return array
     */
    public function getAllFlags()
    {
        return (new ReflectionClass(__CLASS__))->getConstants();
    }

    /**
     * Extracts the given flag into an array of flags used.
     *
     * @param int $flag
     *
     * @return array
     */
    public function extractFlags($flag)
    {
        $flags = [];

        for ($i = 0; $i <= 26; $i++) {
            if ((int) $flag & (1 << $i)) {
                $flags[1 << $i] = 1 << $i;
            }
        }

        return $flags;
    }
}
