/*
    SPDX-FileCopyrightText: 2026 Bharadwaj Raju <bharadwaj.raju@machinesoul.in>

    SPDX-License-Identifier: LGPL-2.0-or-later
*/

#include "snapshotfileitemaction.h"
#include "debug.h"

#include <btrfssnapshots.h>

#include <KIO/JobUiDelegate>
#include <KIO/OpenUrlJob>

#include <Solid/Device>
#include <Solid/StorageAccess>
#include <Solid/StorageVolume>

#include <KFileItem>
#include <KLocalizedString>
#include <KPluginFactory>

#include <QAction>
#include <QDBusMetaType>
#include <QDir>
#include <QIcon>
#include <QList>
#include <QMenu>
#include <QUrl>

using namespace Qt::StringLiterals;

K_PLUGIN_CLASS_WITH_JSON(SnapshotFileItemAction, "snapshotfileitemaction.json")

SnapshotFileItemAction::SnapshotFileItemAction(QObject *parent)
    : KAbstractFileItemActionPlugin(parent)
{
}

QList<QAction *> SnapshotFileItemAction::actions(const KFileItemListProperties &fileItemInfos, QWidget *parentWidget)
{
    QList<QAction *> actions;

    if (fileItemInfos.urlList().length() != 1) {
        return actions;
    }

    QUrl itemUrl = fileItemInfos.urlList().constFirst();
    KFileItem item = fileItemInfos.items().findByUrl(itemUrl);
    if (itemUrl.scheme() == "snapshot"_L1) {
        return actions;
    }

    if (item.isDir()) {
        QString localPath = itemUrl.toLocalFile();
        auto fsDevice = Solid::Device::storageAccessFromPath(localPath);
        auto fsAccess = fsDevice.as<Solid::StorageAccess>();
        if (!fsAccess) {
            qCCritical(SNAPSHOT_FILEITEMACTION()) << "could not determine fs root path for" << localPath;
            return actions;
        }
        QString fsRootPath = fsAccess->filePath();
        auto fsVolume = fsDevice.as<Solid::StorageVolume>();
        if (!fsVolume) {
            qCCritical(SNAPSHOT_FILEITEMACTION()) << "could not determine fs storage volume for" << localPath;
            return actions;
        }
        QString fsUuid = fsVolume->uuid();

        if (BtrfsSnapshots::hasSnapshots(itemUrl.toLocalFile(), fsRootPath)) {
            auto subvolumeIdOpt = BtrfsSnapshots::getSubvolumeForPath(itemUrl.toLocalFile(), fsRootPath);
            if (!subvolumeIdOpt.has_value()) {
                qCCritical(SNAPSHOT_FILEITEMACTION()) << "found snapshots for dir" << itemUrl.toLocalFile() << "but it did not have a subvolume id";
                return actions;
            }
            auto subvolumeId = subvolumeIdOpt.value();
            QAction *action = new QAction(QIcon::fromTheme("view-history"_L1), i18nc("@action:inmenu", "Browse snapshots…"), parentWidget);
            connect(action, &QAction::triggered, this, [this, subvolumeId, fsRootPath, fsUuid]() {
                QUrl targetUrl;
                targetUrl.setScheme("snapshot"_L1);
                if (fsRootPath != "/"_L1) {
                    targetUrl.setHost(fsUuid);
                }
                targetUrl.setPath("/subvolume/"_L1 + QString::number(subvolumeId));
                KIO::OpenUrlJob *job = new KIO::OpenUrlJob(targetUrl, "inode/directory"_L1, this);
                job->start();
            });
            actions << action;
        }
    } else if (item.isLocalFile()) {
        QString localPath = itemUrl.toLocalFile();
        auto fsRoot = Solid::Device::storageAccessFromPath(localPath).as<Solid::StorageAccess>();
        if (!fsRoot) {
            qCCritical(SNAPSHOT_FILEITEMACTION()) << "could not determine fs root path for" << localPath;
            return actions;
        }
        QString fsRootPath = fsRoot->filePath();
        if (BtrfsSnapshots::hasSnapshots(itemUrl.toLocalFile(), fsRootPath)) {
            QAction *action = new QAction(QIcon::fromTheme("view-history"_L1), i18nc("@action:inmenu", "View snapshots…"), parentWidget);
            connect(action, &QAction::triggered, this, [this, item]() {
                QUrl targetUrl;
                targetUrl.setScheme("snapshot"_L1);
                targetUrl.setPath(QDir::cleanPath("/file/"_L1 + item.localPath()));
                KIO::OpenUrlJob *job = new KIO::OpenUrlJob(targetUrl, "inode/directory"_L1, this);
                job->start();
            });
            actions << action;
        }
    }

    return actions;
}

#include "snapshotfileitemaction.moc"
