/*
    SPDX-FileCopyrightText: 2007 Joris Guisson <joris.guisson@gmail.com>
    SPDX-License-Identifier: GPL-2.0-or-later
*/

#ifndef KTGROUP_H
#define KTGROUP_H

#include <QIcon>
#include <QObject>
#include <QString>

#include <ktcore_export.h>
#include <util/constants.h>

namespace bt
{
class BEncoder;
class BDictNode;
class TorrentInterface;
}

namespace kt
{
class QueueManager;
using bt::TorrentInterface;

/**
 * @author Joris Guisson <joris.guisson@gmail.com>
 *
 * Base class for all groups. Subclasses should only implement the
 * isMember function, but can also provide save and load
 * functionality.
 */
class KTCORE_EXPORT Group : public QObject
{
    Q_OBJECT
public:
    enum Properties {
        UPLOADS_ONLY_GROUP = 1,
        DOWNLOADS_ONLY_GROUP = 2,
        MIXED_GROUP = 3,
        CUSTOM_GROUP = 4,
    };

    struct KTCORE_EXPORT Policy {
        QString default_save_location;
        QString default_move_on_completion_location;
        float max_share_ratio;
        float max_seed_time;
        bt::Uint32 max_upload_rate;
        bt::Uint32 max_download_rate;
        bool only_apply_on_new_torrents;

        Policy();
    };

    /**
     * Create a new group.
     * @param name The name of the group
     * @param flags Properties of the group
     * @param path Path in the group tree (e.g /all/downloads/foo, last item in path should be the groups internal name)
     */
    Group(const QString &name, int flags, const QString &path);
    ~Group() override;

    /// See if this is a standard group.
    bool isStandardGroup() const
    {
        return !(flags & CUSTOM_GROUP);
    }

    /// Get the group flags
    int groupFlags() const
    {
        return flags;
    }

    /**
     * Rename the group.
     * @param nn The new name
     */
    void rename(const QString &nn);

    /**
     * Set the group icon by name.
     * @param in The icon name
     */
    void setIconByName(const QString &in);

    /// Get the name of the group
    const QString &groupName() const
    {
        return name;
    }

    /// Get the icon of the group
    const QIcon &groupIcon() const
    {
        return icon;
    }

    /// Name of the group icon
    const QString &groupIconName() const
    {
        return icon_name;
    }

    /// Get the group policy
    const Policy &groupPolicy() const
    {
        return policy;
    }

    /// Path in the group tree
    const QString &groupPath() const
    {
        return path;
    }

    /// Get the number of running torrents
    int runningTorrents() const
    {
        return running;
    }

    /// Total torrents
    int totalTorrents() const
    {
        return total;
    }

    /// Set the group policy
    void setGroupPolicy(const Policy &p);

    /**
     * Save the torrents.The torrents should be save in a bencoded file.
     * @param enc The BEncoder
     */
    virtual void save(bt::BEncoder *enc);

    /**
     * Load the torrents of the group from a BDictNode.
     * @param n The BDictNode
     */
    virtual void load(bt::BDictNode *n);

    /**
     * Test if a torrent is a member of this group.
     * @param tor The torrent
     */
    virtual bool isMember(TorrentInterface *tor) = 0;

    /**
     * The torrent has been removed and is about to be deleted.
     * Subclasses should make sure that they don't have dangling
     * pointers to this torrent.
     * @param tor The torrent
     */
    virtual void torrentRemoved(TorrentInterface *tor);

    /**
     * Subclasses should implement this, if they want to have torrents added to them.
     * @param tor The torrent
     * @param new_torrent Indicates whether this is a newly created or opened torrent
     */
    virtual void addTorrent(TorrentInterface *tor, bool new_torrent);

    /**
     * Subclasses should implement this, if they want to have torrents removed from them.
     * @param tor The torrent
     */
    virtual void removeTorrent(TorrentInterface *tor);

    /**
     * Called when the policy has been changed.
     */
    virtual void policyChanged();

    /**
     * Update the running and total count
     * @param qman The QueueManager
     **/
    void updateCount(QueueManager *qman);

protected:
    QString name;
    QIcon icon;
    QString icon_name;
    int flags;
    Policy policy;
    QString path;
    int running;
    int total;
};

}

#endif
