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

#ifndef KT_DBUS_HH
#define KT_DBUS_HH

#include <QMap>
#include <QObject>
#include <QStringList>

#include <dbus/dbusgroup.h>
#include <dbus/dbustorrent.h>
#include <ktcore_export.h>
#include <util/ptrmap.h>

namespace bt
{
class TorrentInterface;
}

namespace kt
{
class GUIInterface;
class CoreInterface;
class Group;
class DBusSettings;

/**
 * Class which handles DBus calls
 * */
class KTCORE_EXPORT DBus : public QObject
{
    Q_OBJECT
    Q_CLASSINFO("D-Bus Interface", "org.ktorrent.core")
public:
    DBus(GUIInterface *gui, CoreInterface *core, QObject *parent);
    ~DBus() override;

public Q_SLOTS:
    /// Get the names of all torrents
    Q_SCRIPTABLE QStringList torrents();

    /// Start a torrent
    Q_SCRIPTABLE void start(const QString &info_hash);

    /// Stop a torrent
    Q_SCRIPTABLE void stop(const QString &info_hash);

    /// Start all torrents
    Q_SCRIPTABLE void startAll();

    /// Stop all torrents
    Q_SCRIPTABLE void stopAll();

    /// Load a torrent
    Q_SCRIPTABLE void load(const QString &url, const QString &group);

    /// Load a torrent silently
    Q_SCRIPTABLE void loadSilently(const QString &url, const QString &group);

    /// Remove a torrent
    Q_SCRIPTABLE void remove(const QString &info_hash, bool data_to);

    /// Remove a torrent delayed (should be used from signal handlers)
    Q_SCRIPTABLE void removeDelayed(const QString &info_hash, bool data_to);

    /// Set the suspended state
    Q_SCRIPTABLE void setSuspended(bool suspend);

    /// Gets the global suspended state
    Q_SCRIPTABLE bool suspended();

    /// Order the Queue
    Q_SCRIPTABLE void orderQueue();

    /// Reindex the queue
    Q_SCRIPTABLE void reindexQueue();

    /// Get all the custom groups
    Q_SCRIPTABLE QStringList groups() const;

    /// Add a group
    Q_SCRIPTABLE bool addGroup(const QString &group);

    /// Remove a group
    Q_SCRIPTABLE bool removeGroup(const QString &group);

    /// Get a torrent (this is for scripting)
    Q_SCRIPTABLE QObject *torrent(const QString &info_hash);

    /// Get a group (this is for scripting)
    Q_SCRIPTABLE QObject *group(const QString &name);

    /// Get the settings (this is for scripting)
    Q_SCRIPTABLE QObject *settings();

    /// Write something to the log
    Q_SCRIPTABLE void log(const QString &line);

    ///  Get the number of torrents running.
    Q_SCRIPTABLE uint numTorrentsRunning() const;

    ///  Get the number of torrents not running.
    Q_SCRIPTABLE uint numTorrentsNotRunning() const;

    ///  Get the number of torrents not running.
    Q_SCRIPTABLE QString dataDir() const;

private Q_SLOTS:
    void torrentAdded(bt::TorrentInterface *tc);
    void torrentRemoved(bt::TorrentInterface *tc);
    void finished(bt::TorrentInterface *tc);
    void torrentStoppedByError(bt::TorrentInterface *tc, QString msg);
    void groupAdded(Group *g);
    void groupRemoved(Group *g);
    void delayedTorrentRemoval();

Q_SIGNALS:
    /// DBus signal emitted when a torrent has been added
    Q_SCRIPTABLE void torrentAdded(const QString &tor);

    /// DBus signal emitted when a torrent has been removed
    Q_SCRIPTABLE void torrentRemoved(const QString &tor);

    /// Emitted when torrent is finished
    Q_SCRIPTABLE void finished(const QString &tor);

    /// Emitted when a torrent is stopped by an error
    Q_SCRIPTABLE void torrentStoppedByError(const QString &tor, const QString &msg);

    /// Emitted when settings are changed in settings dialog
    Q_SCRIPTABLE void settingsChanged();

    /// Emitted when suspended state changes
    Q_SCRIPTABLE void suspendStateChanged(bool suspended);

private:
    GUIInterface *gui;
    CoreInterface *core;
    bt::PtrMap<QString, DBusTorrent> torrent_map;
    bt::PtrMap<Group *, DBusGroup> group_map;
    QMap<QString, bool> delayed_removal_map;
    DBusSettings *dbus_settings;

    typedef bt::PtrMap<QString, DBusTorrent>::iterator DBusTorrentItr;
    typedef bt::PtrMap<Group *, DBusGroup>::iterator DBusGroupItr;
};

}

#endif
