/*
 * Copyright 2023 KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef APPINFO_H
#define APPINFO_H

#include <QObject>
#include "policy.h"
#include <KWindowSystem>
#include <QDebug>
#include <QMetaType>

namespace appinfo {

enum AppType {
    Normal,
    Kmre,
};

enum RunningStatus {
    None,
    Launching,
    Running,
    Finished,
    Error,
};

struct AppInstance
{
    QString instName;
    QString cgroupName;
    QStringList args;
    QList<int> pids;
    quint64 timerId = 0;
    Policy::AppStatus appStatus;
    RunningStatus appRunningStaus;
    AppType appType;
    int64_t launchTimestamp;
    QList<quint32> wids;
    QString mprisDbus;
    bool operator==(const AppInstance &other) {
        return instName == other.instName &&
                cgroupName == other.cgroupName &&
                args == other.args &&
                pids == other.pids &&
                timerId == other.timerId &&
                appStatus == other.appStatus &&
                appRunningStaus == other.appRunningStaus &&
                appType == other.appType &&
                launchTimestamp == other.launchTimestamp &&
                wids == other.wids &&
                mprisDbus == other.mprisDbus;
    }
};

class AppInfo : public QObject
{
    Q_OBJECT
public:

    explicit AppInfo(QObject *parent = nullptr);
    explicit AppInfo(const QString &id,
                     const QString &desktopFile,
                     AppType appType,
                     QObject *parent = nullptr);
    AppInfo(const appinfo::AppInfo &other);
    bool operator==(const appinfo::AppInfo &other);
    AppInfo operator= (const appinfo::AppInfo &other);

    /**
     * @brief id
     * @return
     */
    QString appId() const;

    /**
     * @brief desktopFile
     * @return
     */
    QString desktopFile() const;

    AppType appType() const;

    /**
     * @brief instances
     * @return
     */
    QList<AppInstance> instances() const;

    void appendAppInstance(const AppInstance &inst);

    QString cgroupName(const QString &instName) const;
    QStringList cgroupNames(Policy::AppStatus status) const;

    QString mprisDbus(const QString &instName) const;
    void setMprisDbus(const QString &instName, const QString &mprisDBusName);

    quint64 instanceTimerId(const QString &instName) const;
    void setInstanceTimerId(const QString &instName, quint64 timerId);

    bool appInstanceIsHidden(const QString &instName) const;

    void setInstanceStatus(const QString &name, Policy::AppStatus status);
    int instanceStatus(const QString &name);

    void setInstanceRunningStatus(const QString &name, RunningStatus status);

    void setInstanceAppType(const QString &name, AppType type);
    /**
     * @brief removeAppInstance
     * @param id
     * @param inst
     */
    void removeAppInstance(const QString &inst);

    /**
     * @brief appendAppWid
     * @param id
     * @param inst
     * @param wid
     */
    void appendAppWid(const QString &inst, const quint32 &wid);
    QList<quint32> appInstanceWids(const QString &inst) const;

    /**
     * @brief removeAppWid
     * @param id
     * @param inst
     */
    void removeAppWid(const QString &inst, const quint32 &wid);

    void appendPid(const QString &inst, const int &pid);
    void removePid(const QString &inst, const int &pid);
    QList<int> pids(const QString &inst) const;

private:
    QList<AppInstance> m_instances;
    QString m_appId;
    QString m_desktopFile;
    AppType m_appType;
};

}
// namespace appinfo

#endif // APPINFO_H
