/*
  This file is part of libkldap.
  SPDX-FileCopyrightText: 2004-2006 Szombathelyi György <gyurco@freemail.hu>

  SPDX-License-Identifier: LGPL-2.0-or-later
*/

#pragma once

#include <QString>
#include <memory>

#include "kldap_core_export.h"
#include "ldapserver.h"
#include "ldapurl.h"

namespace KLDAPCore
{
/*!
 * \class KLDAPCore::LdapConnection
 * \inmodule LdapCore
 * \inheaderfile KLDAPCore/LdapConnection
 *
 * \brief
 * This class represents a connection to an LDAP server.
 */
class KLDAP_CORE_EXPORT LdapConnection
{
public:
    enum SASL_Fields {
        SASL_Authname = 0x1,
        SASL_Authzid = 0x2,
        SASL_Realm = 0x4,
        SASL_Password = 0x8,
    };

    /*! Constructs an LdapConnection object */
    LdapConnection();
    /*! Constructs an LdapConnection with the parameters given in url */
    explicit LdapConnection(const LdapUrl &url);
    /*! Constructs an LdapConnection with the parameters given in server */
    explicit LdapConnection(const LdapServer &server);

    ~LdapConnection();

    /*!
     * Sets the connection parameters via the specified url. After this,
     * you need to call connect() to connect with the new parameters.
     * \a url the URL containing the connection parameters
     */
    void setUrl(const LdapUrl &url);
    /*!
     * Returns the connection parameters which was specified with an LDAP Url
     * or a LdapServer structure.
     */
    const LdapServer &server() const;
    /*!
     * Sets the connection parameters via the specified server structure. After
     * this, you need to call connect() to connect with the new parameters.
     * \a server the server object containing the connection parameters
     */
    void setServer(const LdapServer &server);

    /*!
     * Sets up the connection parameters with creating a handle to the LDAP server.
     * Also sets sizelimit and timelimit and starts TLS if it is requested.
     * Returns 0 if successful, else returns an LDAP error code, and an error
     * string which is available via connectionError().
     */
    int connect();
    /*!
     * Returns a translated error string if connect() failed.
     */
    [[nodiscard]] QString connectionError() const;
    /*!
     *  Closes the LDAP connection.
     */
    void close();

    /*! Sets the size limit for the connection.
     *  \a sizelimit the connection size limit to set
     */
    [[nodiscard]] bool setSizeLimit(int sizelimit);
    /*! Returns the current size limit. */
    [[nodiscard]] int sizeLimit() const;

    /*! Sets the time limit for the connection.
     *  \a timelimit the connection time limit to set
     */
    [[nodiscard]] bool setTimeLimit(int timelimit);
    /*! Returns the current time limit. */
    [[nodiscard]] int timeLimit() const;

    /*! Gets an option from the connection. The option value can be client
     * library specific, so avoid this function if possible
     * \a option the connection option to return
     * \a value the value of option to get
     */
    [[nodiscard]] int getOption(int option, void *value) const;
    /*! Sets an option in the connection. The option value can be client
     * library specific, so avoid this function if possible */
    int setOption(int option, void *value);

    /*! Returns the LDAP error code from the last operation */
    [[nodiscard]] int ldapErrorCode() const;
    /*! Returns the LDAP error string from the last operation */
    [[nodiscard]] QString ldapErrorString() const;
    /*! Returns a translated error message from the specified LDAP error code */
    [[nodiscard]] static QString errorString(int code);

    /*! Returns the SASL error string from the last SASL operation */
    [[nodiscard]] QString saslErrorString() const;

    /*!
     * Returns the opaqe client-library specific LDAP object.
     * Avoid its usage if you can.
     */
    void *handle() const;

    /*!
     * Returns the opaqe sasl-library specific SASL object.
     * Avoid its usage if you can.
     */
    void *saslHandle() const;

private:
    class LdapConnectionPrivate;
    std::unique_ptr<LdapConnectionPrivate> const d;

    Q_DISABLE_COPY(LdapConnection)
};
}
