/*
    SPDX-FileCopyrightText: 2010-2016 Ivan Cukic <ivan.cukic(at)kde.org>

    SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/

#ifndef ACTIVITIES_INFO_H
#define ACTIVITIES_INFO_H

#include <QFuture>
#include <QObject>
#include <QString>

#include "plasma_activities_export.h"

#include <memory>

namespace KActivities
{
class InfoPrivate;

/*!
 * \class KActivities::Info
 * \inmodule PlasmaActivities
 * \inheaderfile PlasmaActivities/Info
 *
 * \brief Info about an activity.
 *
 * Most methods in it require a
 * semantic backend running to function properly.
 *
 * This class is not thread-safe.
 *
 * The API of the class is synchronous, but the most used properties
 * are pre-fetched and cached. This means that, in order to get the least
 * amount of d-bus related locks, you should declare long-lived instances
 * of this class.
 *
 * Before relying on the values retrieved by the class, make sure that the
 * state is not Info::Unknown. You can get invalid data either because the
 * service is not functioning properly (or at all) or because the class did
 * not have enough time to synchronize the data with it.
 *
 * For example, if this is the only existing instance of the Info class, the
 * name method will return an empty string.
 *
 * For example, this is wrong (works, but blocks):
 * \code
 * void someMethod(const QString & activity) {
 *     // Do not copy. This approach is not a good one!
 *     Info info(activity);
 *     doSomethingWith(info.name());
 * }
 * \endcode
 *
 * Instances of the Info class should be long-lived. For example, members
 * of the classes that use them, and you should listen for the changes in the
 * provided properties.
 *
 * \since 4.5
 */
class PLASMA_ACTIVITIES_EXPORT Info : public QObject
{
    Q_OBJECT

    /*!
     * \property KActivities::Info::id
     */
    Q_PROPERTY(QString id READ id)

    /*!
     * \property KActivities::Info::name
     */
    Q_PROPERTY(QString name READ name NOTIFY nameChanged)

    /*!
     * \property KActivities::Info::description
     */
    Q_PROPERTY(QString description READ description NOTIFY descriptionChanged)

    /*!
     * \property KActivities::Info::icon
     */
    Q_PROPERTY(QString icon READ icon NOTIFY iconChanged)

    /*!
     * \property KActivities::Info::isCurrent
     */
    Q_PROPERTY(bool isCurrent READ isCurrent NOTIFY isCurrentChanged)

public:
    /*!
     *
     */
    explicit Info(const QString &activity, QObject *parent = nullptr);
    ~Info() override;

    /*!
     * Specifies which parts of this class are functional
     *
     * \value Nothing No activity info provided (isValid is false)
     * \value BasicInfo Basic info is provided
     * \value Everything Everything is available
     */
    enum Availability {
        Nothing = 0,
        BasicInfo = 1,
        Everything = 2,
    };

    /*!
     * Returns what info is provided by this instance of Info
     */
    Availability availability() const;

    /*!
     * Returns the URI of this activity. The same URI is used by activities
     * KIO worker.
     */
    QString uri() const;

    /*!
     * Returns the id of the activity
     */
    QString id() const;

    /*!
     * Returns whether this activity is the current one
     */
    bool isCurrent() const;

    /*!
     * Returns the name of the activity
     */
    QString name() const;

    /*!
     * Returns the description of the activity
     */
    QString description() const;

    /*!
     * Returns the icon of the activity. Icon can be a freedesktop.org name or
     * a file path. Or empty if no icon is set.
     */
    QString icon() const;

Q_SIGNALS:
    /*!
     * Emitted when the activity's name, icon or some custom property is changed
     */
    void infoChanged();

    /*!
     * Emitted when the name is changed
     */
    void nameChanged(const QString &name);

    /*!
     * Emitted when the activity becomes the current one, or when it stops
     * being the current one
     */
    void isCurrentChanged(bool current);

    /*!
     * Emitted when the description is changed
     */
    void descriptionChanged(const QString &description);

    /*!
     * Emitted when the icon was changed
     */
    void iconChanged(const QString &icon);

    /*!
     * Emitted when the activity is added
     */
    void added();

    /*!
     * Emitted when the activity is removed
     */
    void removed();

private:
    const std::unique_ptr<InfoPrivate> d;

    Q_PRIVATE_SLOT(d, void added(const QString &))
    Q_PRIVATE_SLOT(d, void removed(const QString &))
    Q_PRIVATE_SLOT(d, void infoChanged(const QString &))
    Q_PRIVATE_SLOT(d, void nameChanged(const QString &, const QString &))
    Q_PRIVATE_SLOT(d, void descriptionChanged(const QString &, const QString &))
    Q_PRIVATE_SLOT(d, void iconChanged(const QString &, const QString &))
    Q_PRIVATE_SLOT(d, void setCurrentActivity(const QString &))

    friend class InfoPrivate;
};

} // namespace KActivities

#endif // ACTIVITIES_INFO_H
