/*
    This file is part of the KDE libraries
    SPDX-FileCopyrightText: 1999 Torben Weis <weis@kde.org>
    SPDX-FileCopyrightText: 2000-2001 Waldo Bastian <bastian@kde.org>
    SPDX-FileCopyrightText: 2012 David Faure <faure@kde.org>

    SPDX-License-Identifier: LGPL-2.0-only
*/

#ifndef KPROTOCOLINFO_H
#define KPROTOCOLINFO_H

#include "kiocore_export.h"
#include <QMetaType>
#include <QStringList>

/*!
 * \class KProtocolInfo
 * \inmodule KIOCore
 *
 * \brief Information about I/O (Internet, etc.) protocols supported by KDE.

 * KProtocolInfo is useful if you want to know which protocols
 * KDE supports. In addition you can find out lots of information
 * about a certain protocol. All of the functionality is provided by the static
 * methods.
 * The implementation scans the *.protocol files of all installed KIO workers to get
 * this information and stores the result into an internal cache.
 *
 * *.protocol files are installed in the "services" resource.
 *
 * The KProtocolInfo methods are reentrant (i.e. can be called from multiple threads simultaneously).
 */
class KIOCORE_EXPORT KProtocolInfo
{
public:
    //
    // Static functions:
    //

    /*!
     * Returns list of all known protocols.
     */
    static QStringList protocols();

    /*!
     * Returns whether a protocol is installed that is able to handle \a url.
     *
     * \a url the url to check
     */
    static bool isKnownProtocol(const QUrl &url);

    /*!
     * Same as above except you can supply just the protocol instead of
     * the whole URL.
     */
    static bool isKnownProtocol(const QString &protocol, bool updateCacheIfNotfound = true);

    /*!
     * Returns the library / executable to open for the protocol \a protocol
     * Example : "kio_ftp", meaning either the executable "kio_ftp" or
     * the library "kio_ftp.la" (recommended), whichever is available.
     *
     * This corresponds to the "exec=" field in the protocol description file.
     *
     * \a protocol the protocol to check
     *
     * Returns the executable of library to open, or QString() for
     *         unsupported protocols
     */
    static QString exec(const QString &protocol);

    /*!
     * Describes the type of a protocol.
     * For instance ftp:// appears as a filesystem with folders and files,
     * while bzip2:// appears as a single file (a stream of data),
     * and telnet:// doesn't output anything.
     *
     * \value T_STREAM stream of data (e.g.\ single file)
     * \value T_FILESYSTEM structured directory
     * \value T_NONE no information about the type available
     * \value T_ERROR used to signal an error
     */
    enum Type {
        T_STREAM,
        T_FILESYSTEM,
        T_NONE,
        T_ERROR,
    };

    /*!
     * \inmodule KIOCore
     * Definition of an extra field in the UDS entries, returned by a listDir operation.
     *
     * The name is the name of the column, translated.
     *
     * The type name comes from QMetaType::name()
     * Currently supported types: "QString", "QDateTime" (ISO-8601 format)
     */
    struct ExtraField {
        /*!
         * \value String
         * \value DateTime
         * \value Invalid
         */
        enum Type {
            String = QMetaType::QString,
            DateTime = QMetaType::QDateTime,
            Invalid = QMetaType::UnknownType
        };

        ExtraField()
            : type(Invalid)
        {
        }
        ExtraField(const QString &_name, Type _type)
            : name(_name)
            , type(_type)
        {
        }
        QString name;
        Type type;
    };
    /*!
     * TODO qdoc?
     */
    typedef QList<ExtraField> ExtraFieldList;
    /*!
     * Definition of extra fields in the UDS entries, returned by a listDir operation.
     *
     * This corresponds to the "ExtraNames=" and "ExtraTypes=" fields in the protocol description file.
     * Those two lists should be separated with ',' in the protocol description file.
     * See ExtraField for details about names and types
     */
    static ExtraFieldList extraFields(const QUrl &url);

    /*!
     * Returns whether the protocol can act as a helper protocol.
     * A helper protocol invokes an external application and does not return
     * a file or stream.
     *
     * This corresponds to the "helper=" field in the protocol description file.
     * Valid values for this field are "true" or "false" (default).
     *
     * \a url the url to check
     *
     * Returns \c true if the protocol is a helper protocol (e.g. vnc), false
     *              if not (e.g. http)
     */
    static bool isHelperProtocol(const QUrl &url);

    /*!
     * Same as above except you can supply just the protocol instead of
     * the whole URL.
     */
    static bool isHelperProtocol(const QString &protocol);

    /*!
     * Returns whether the protocol can act as a filter protocol.
     *
     * A filter protocol can operate on data that is passed to it
     * but does not retrieve/store data itself, like gzip.
     * A filter protocol is the opposite of a source protocol.
     *
     * The "source=" field in the protocol description file determines
     * whether a protocol is a source protocol or a filter protocol.
     * Valid values for this field are "true" (default) for source protocol or
     * "false" for filter protocol.
     *
     * \a url the url to check
     *
     * Returns \c true if the protocol is a filter (e.g. gzip), false if the
     *         protocol is a helper or source
     */
    static bool isFilterProtocol(const QUrl &url);

    /*!
     * Same as above except you can supply just the protocol instead of
     * the whole URL.
     */
    static bool isFilterProtocol(const QString &protocol);

    /*!
     * Returns the name of the icon, associated with the specified protocol.
     *
     * This corresponds to the "Icon=" field in the protocol description file.
     *
     * \a protocol the protocol to check
     *
     * Returns the icon of the protocol, or an empty string if unknown
     */
    static QString icon(const QString &protocol);

    /*!
     * Returns the name of the config file associated with the
     * specified protocol. This is useful if two similar protocols
     * need to share a single config file, e.g. http and https.
     *
     * This corresponds to the "config=" field in the protocol description file.
     *
     * \a protocol the protocol to check
     *
     * Returns the config file, or an empty string if unknown
     */
    static QString config(const QString &protocol);

    /*!
     * Returns the soft limit on the number of KIO workers for this protocol.
     * This limits the number of workers used for a single operation, note
     * that multiple operations may result in a number of instances that
     * exceeds this soft limit.
     *
     * This corresponds to the "maxInstances=" field in the protocol's worker metadata.
     * The default is 1.
     *
     * \a protocol the protocol to check
     *
     * Returns the maximum number of workers, or 1 if unknown
     *
     * \since 5.101
     */
    static int maxWorkers(const QString &protocol);

    /*!
     * Returns the limit on the number of KIO workers for this protocol per host.
     *
     * This corresponds to the "maxInstancesPerHost=" field in the protocol's worker metadata.
     * The default is 0 which means there is no per host limit.
     *
     * \a protocol the protocol to check
     *
     * Returns the maximum number of workers, or 1 if unknown
     *
     * \since 5.101
     */
    static int maxWorkersPerHost(const QString &protocol);

    /*!
     * Returns whether MIME types can be determined based on extension for this
     * protocol. For some protocols, e.g. http, the filename extension in the URL
     * can not be trusted to truly reflect the file type.
     *
     * This corresponds to the "determineMimetypeFromExtension=" field in the protocol description file.
     * Valid values for this field are "true" (default) or "false".
     *
     * \a protocol the protocol to check
     *
     * Returns \c true if the MIME types can be determined by extension
     */
    static bool determineMimetypeFromExtension(const QString &protocol);

    /*!
     * Returns the default MIME type for the specified protocol, if one exists.
     *
     * This corresponds to the "defaultMimetype=" field in the protocol description file.
     *
     * \a protocol the protocol to check
     *
     * Returns the default MIME type of the protocol, or an empty string if none set or protocol unknown
     * \since 5.60
     */
    static QString defaultMimetype(const QString &protocol);

    /*!
     * Returns the documentation path for the specified protocol.
     *
     * This corresponds to the "X-DocPath=" or "DocPath=" field in the protocol description file.
     *
     * \a protocol the protocol to check
     *
     * Returns the docpath of the protocol, or an empty string if unknown
     */
    static QString docPath(const QString &protocol);

    /*!
     * Returns the protocol class for the specified protocol.
     *
     * This corresponds to the "Class=" field in the protocol description file.
     *
     * The following classes are defined:
     * \list
     * \li ":internet" for common internet protocols
     * \li ":local" for protocols that access local resources
     * \endlist
     *
     * Protocol classes always start with a ':' so that they can not be confused with
     * the protocols themselves.
     *
     * \a protocol the protocol to check
     *
     * Returns the class of the protocol, or an empty string if unknown
     */
    static QString protocolClass(const QString &protocol);

    /*!
     * Returns whether file previews should be shown for the specified protocol.
     *
     * This corresponds to the "ShowPreviews=" field in the protocol description file.
     *
     * By default previews are shown if protocolClass is :local.
     *
     * \a protocol the protocol to check
     *
     * Returns \c true if previews should be shown by default, false otherwise
     */
    static bool showFilePreview(const QString &protocol);

    /*!
     * Returns the list of capabilities provided by the KIO worker implementing
     * this protocol.
     *
     * This corresponds to the "Capabilities=" field in the protocol description file.
     *
     * The capability names are not defined globally, they are up to each
     * worker implementation. For example when adding support for a new
     * special command for mounting, one would add the string "Mount" to the
     * capabilities list, and applications could check for that string
     * before sending a special() command that would otherwise do nothing
     * on older KIO worker implementations.
     *
     * \a protocol the protocol to check
     *
     * Returns the list of capabilities.
     */
    static QStringList capabilities(const QString &protocol);

    /*!
     * Returns the list of archive MIME types handled by the KIO worker implementing
     * this protocol.
     *
     * This corresponds to the "archiveMimetype=" field in the protocol description file.
     *
     * \a protocol the protocol to check
     *
     * Returns the list of archive MIME types (e.g. application/x-zip) handled.
     * \since 5.23
     */
    static QStringList archiveMimetypes(const QString &protocol);

#if KIOCORE_ENABLE_DEPRECATED_SINCE(6, 4)
    /*!
     * Returns the name of the protocol through which the request
     * will be routed if proxy support is enabled.
     *
     * A good example of this is the ftp protocol for which proxy
     * support is commonly handled by the http protocol.
     *
     * This corresponds to the "ProxiedBy=" in the protocol description file.
     *
     * Not used.
     *
     * \deprecated[6.4]
     */
    KIOCORE_DEPRECATED_VERSION(6, 4, "Not used")
    static QString proxiedBy(const QString &protocol);
#endif

    typedef enum {
        Name,
        FromUrl,
        DisplayName
    } FileNameUsedForCopying;

private:
    Q_DISABLE_COPY(KProtocolInfo)
};

#endif
