// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
// SPDX-FileCopyrightText: 2020-2022 Harald Sitter <sitter@kde.org>

#pragma once

#include <QAbstractListModel>
#include <QByteArray>
#include <QDBusObjectPath>
#include <QDBusPendingCallWatcher>
#include <QList>
#include <QMap>
#include <QObject>
#include <QString>
#include <QStringList>
#include <QVariant>

class ComFeralinteractiveGameModeInterface;

class GamesModel : public QAbstractListModel
{
    Q_OBJECT
    /// Whether kded is available and connected
    Q_PROPERTY(bool valid READ valid NOTIFY validChanged)
    /// Whether we are waiting for GetManagedObjects (i.e. initial listing)
    Q_PROPERTY(bool waiting READ waiting NOTIFY waitingChanged)
    Q_PROPERTY(bool serviceRegistered MEMBER m_serviceRegistered NOTIFY serviceRegisteredChanged)
    Q_PROPERTY(int rowCount READ rowCount NOTIFY rowCountChanged)
public:
    enum ItemRole {
        ObjectRole = Qt::UserRole + 1,
        LastRole = ObjectRole,
    };

    explicit GamesModel(QObject *parent = nullptr);

    QHash<int, QByteArray> roleNames() const final;

    int rowCount(const QModelIndex &parent = QModelIndex()) const final;
    Q_SIGNAL void rowCountChanged();

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

    Q_SCRIPTABLE int role(const QByteArray &roleName) const;

    bool valid() const;
    bool waiting() const;

Q_SIGNALS:
    void validChanged();
    void waitingChanged();
    void serviceRegisteredChanged();

private Q_SLOTS:
    void addObject(int pid, const QDBusObjectPath &dbusPath);
    void removeObject(int pid, const QDBusObjectPath &dbusPath);
    void reset();
    void reload();

private:
    void initRoleNames(QObject *object);

    bool m_serviceRegistered = false;

    QVector<QObject *> m_objects;

    QHash<int, QByteArray> m_roles;
    QHash<int, QByteArray> m_objectProperties;
    QHash<int, int> m_signalIndexToProperties;

    ComFeralinteractiveGameModeInterface *m_iface = nullptr;
    QDBusPendingCallWatcher *m_getManagedObjectsWatcher = nullptr;
};

Q_DECLARE_METATYPE(GamesModel *)
