/* kldapclient.h - LDAP access
 * SPDX-FileCopyrightText: 2002 Klarälvdalens Datakonsult AB
 * SPDX-FileContributor: Steffen Hansen <hansen@kde.org>
 *
 * SPDX-License-Identifier: LGPL-2.0-or-later
 */

#pragma once

#include "kldap_core_export.h"

#include <KLDAPCore/LdapObject>
#include <QObject>
#include <QStringList>

namespace KLDAPCore
{
class LdapClient;
/*!
 * Describes the result returned by an LdapClientSearch query.
 *
 * \since 4.14
 */
struct LdapResultObject {
    using List = QList<LdapResultObject>;
    const KLDAPCore::LdapClient *client = nullptr;
    KLDAPCore::LdapObject object;
};

/*!
 * Describes the result returned by an LdapClientSearch query.
 *
 * \since 4.5
 */
struct LdapResult {
    /*!
     * A list of LdapResult objects.
     */
    using List = QList<LdapResult>;

    KLDAPCore::LdapDN dn;
    QString name; ///< The full name of the contact.
    QStringList email; ///< The list of emails of the contact.
    int clientNumber; ///< The client the contact comes from (used for sorting in a ldap-only lookup).
    int completionWeight; ///< The weight of the contact (used for sorting in a completion list).
};

/*!
 * \class KLDAPCore::LdapClientSearch
 * \inmodule LdapCore
 * \inheaderfile KLDAPCore/LdapClientSearch
 *
 * \since 4.5
 */
class KLDAP_CORE_EXPORT LdapClientSearch : public QObject
{
    Q_OBJECT

public:
    /*!
     * Creates a new LDAP client search object.
     * \param parent the parent object
     */
    explicit LdapClientSearch(QObject *parent = nullptr);

    /*!
     * Creates a new LDAP client search object with specified attributes.
     * \param attr the list of attributes to search for
     * \param parent the parent object
     */
    explicit LdapClientSearch(const QStringList &attr, QObject *parent = nullptr);

    /*!
     * Destroys the LDAP client search object.
     */
    ~LdapClientSearch() override;

    /*!
     * Starts the LDAP search on all configured LDAP clients with the given search \a query.
     */
    void startSearch(const QString &query);

    /*!
     * Cancels the currently running search query.
     */
    void cancelSearch();

    /*!
     * Returns whether LDAP search is possible at all.
     *
     * Note: This method can return false if either no LDAP is configured
     *       or the system does not support the KIO LDAP protocol.
     * \return true if LDAP search is available, false otherwise
     */
    [[nodiscard]] bool isAvailable() const;

    /*!
     * Updates the completion weights for the configured LDAP clients from
     * the configuration file.
     */
    void updateCompletionWeights();

    /*!
     * Returns the list of configured LDAP clients.
     */
    [[nodiscard]] QList<KLDAPCore::LdapClient *> clients() const;

    /*!
     * Returns the filter for the search query.
     * \return the LDAP filter string
     * \since 4.14
     */
    [[nodiscard]] QString filter() const;

    /*!
     * Sets the filter for the search query.
     * \param filter the LDAP filter string to set
     * \since 4.14
     */
    void setFilter(const QString &filter);

    /*!
     * Returns the attributes that are queried from the LDAP server.
     * \return the list of attribute names
     * \since 4.14
     */
    [[nodiscard]] QStringList attributes() const;

    /*!
     * Sets the attributes that are queried from the LDAP server.
     * \param attributes the list of attribute names to query
     * \since 4.14
     */
    void setAttributes(const QStringList &attributes);

    [[nodiscard]] static QStringList defaultAttributes();

Q_SIGNALS:
    /*!
     * This signal is emitted whenever new contacts have been found
     * during the lookup.
     *
     * \a results The contacts in the form "Full Name <email>"
     */
    void searchData(const QStringList &results);

    /*!
     * This signal is emitted whenever new contacts have been found
     * during the lookup.
     *
     * \a results The list of found contacts.
     */
    void searchData(const KLDAPCore::LdapResult::List &results);

    /*!
     * This signal is emitted whenever new contacts have been found
     * during the lookup.
     *
     * \a results The list of found contacts.
     */
    void searchData(const KLDAPCore::LdapResultObject::List &results);

    /*!
     * This signal is emitted whenever the lookup is complete or the
     * user has canceled the query.
     */
    void searchDone();

private:
    class LdapClientSearchPrivate;
    std::unique_ptr<LdapClientSearchPrivate> const d;
};
}
Q_DECLARE_TYPEINFO(KLDAPCore::LdapResult, Q_RELOCATABLE_TYPE);
Q_DECLARE_TYPEINFO(KLDAPCore::LdapResultObject, Q_RELOCATABLE_TYPE);
