/*
 * Peony-Qt's Library
 *
 * Copyright (C) 2019, Tianjin KYLIN Information Technology Co., Ltd.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this library.  If not, see <https://www.gnu.org/licenses/>.
 *
 * Authors: Yue Lan <lanyue@kylinos.cn>
 *
 */

#include "compatible-open-menu-plugin.h"
#include <file-info.h>
#include <stdlib.h>
#include <QAction>
#include <QUrl>
#include <QDir>
#include <QFile>
#include <QProcess>
#include <QSettings>
#include <QTextCodec>
#include <QTranslator>
#include <QLocale>
#include <QApplication>
#include <unistd.h>
#include <QDebug>
#include <QInputDialog>
#include <QMessageBox>
#include <QRegularExpression>
#include <QCryptographicHash>
#include <gio/gio.h>
#include "dialog.h"
#include <QTextStream>
#include <QString>
#include <QDBusInterface>
#include <QDBusReply>
#include <QRegularExpression>

using namespace Peony;

CompatibleOpenMenuPlugin::CompatibleOpenMenuPlugin(QObject *parent) : QObject(parent)
{
    QTranslator *t = new QTranslator(this);
    qDebug() << "\n\n\n\n\n\n\ntranslate:" << t->load(":/translations/peony-compatible-open-extension_" + QLocale::system().name());
    QApplication::installTranslator(t);
}

QList<QAction *> CompatibleOpenMenuPlugin::menuActions(Types types, const QString &uri, const QStringList &selectionUris)
{
    qInstallMessageHandler(myMessageOutput);
    qDebug() << "DEBUG - Useless: uri - " << uri;
    QList<QAction *> actions;
    if (types == MenuPluginInterface::DirectoryView || types == MenuPluginInterface::DesktopWindow)
    {
        if (selectionUris.isEmpty())
        {
            return actions;
        }
        if (selectionUris.count() == 1)
        {
            QString decodeName = QUrl::fromPercentEncoding(selectionUris.first().toUtf8());
            if (!decodeName.startsWith("file://") || !decodeName.endsWith(".desktop"))
            {
                return actions;
            }

            QStringList decodeNameList = decodeName.split("/");
            QString desktopName = decodeNameList.last();

            bool resFlag = false;
            QDir envDir("/");
            envDir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden);
            QStringList filter;
            filter << "fs.old-*" << ".fs.old-*";
            QStringList envDirList = envDir.entryList(filter);
            QStringList desktopScopeList;
            for (int i = 0; i < envDirList.length(); i++)
            {
                desktopScopeList << "/" + envDirList.at(i) + "/var/cache/RevisionsManager/compat-desktops";
            }
            desktopScopeList << "/usr/share/kylin-os-manager/replacement/desktop.list";
            for (int j = 0; j < desktopScopeList.length(); j++)
            {
                QString desktopScope = desktopScopeList.at(j);
                QFile file(desktopScope);
                if (!file.open(QIODevice::ReadOnly))
                {
                    qDebug() << "WARNING - Failed to Open Compatible/HJZS App Desktop List = " << desktopScope;
                }
                else
                {
                    QTextStream in(&file);
                    while (!in.atEnd())
                    {
                        QString line = in.readLine();
                        if (line.contains(desktopName))
                        {
                            resFlag = true;
                            break;
                        }
                    }
                }
            }
            if (!resFlag)
            {
                qDebug() << "WARNING - 该应用不属于兼容应用/换机应用,不支持右键兼容打开";
                return actions;
            }
            QString desktopPath = decodeName.remove("file://");
            qDebug() << "DEBUG - desktopPath: " << decodeName;

            // 读取desktop文件
            QSettings ini(desktopPath, QSettings::IniFormat);
            ini.setIniCodec(QTextCodec::codecForName("UTF8"));

            // 取 Exec 值
            QString execValue = ini.value("Desktop Entry/Exec").toString();
            qDebug() << "DEBUG - execValue: " << execValue;

            QString execFile = execValue;
            execFile.remove(QRegularExpression(" %[a-zA-Z]"));
            execFile.remove(QRegularExpression(" --.*"));
            qDebug() << "DEBUG - execFile: " << execFile;

            QString fileTmp = execValue;
            fileTmp.remove(QRegularExpression(" %[a-zA-Z]"));
            fileTmp.remove(QRegularExpression(" --.*"));
            fileTmp.remove("KARE");
            QString fileKAREBAK = fileTmp + "_KAREBAK";
            QFile fK(fileKAREBAK);
            if (!fK.exists())
            {
                qDebug() << "ERROR - 兼容执行文件: " << fileKAREBAK << " Not Exists";
                return actions;
            }
            if (!fK.open(QIODevice::ReadOnly | QIODevice::Text))
            {
                qDebug() << "ERROR - 兼容执行文件: " << fileKAREBAK << " Can Not Open";
                return actions;
            }
            QString main = fK.readAll();
            main = main.trimmed();

            QString execOrigin = execValue;
            QStringList execPart = execOrigin.split("/");
            QString execAidPart = execPart.last();
            QStringList aidPart = execAidPart.split(" ");
            QString execKernel = aidPart.first();
            qDebug() << "DEBUG - execKernel: " << execKernel;

            QAction *dirAction = new QAction(QIcon::fromTheme("xjump"), tr("Open in Compatible Mode"), nullptr);
            dirAction->connect(dirAction, &QAction::triggered, [ = ]()
            {
                Dialog *dialog = new Dialog(execKernel);
                QString selectedOption = "UbuntuKylin22.04";
                bool model = false;
                if (dialog->exec() == QDialog::Accepted)
                {
                    selectedOption = dialog->getItem();
                    model = dialog->storePrefer();
                }
                else
                {
                    qDebug() << "DEBUG - 用户点击了取消按钮或关闭了对话框";
                    return;
                }
                qDebug() << "DEBUG - 用户最终选择的兼容环境为: " << selectedOption;
                qDebug() << "DEBUG - 用户选择是否记住兼容模式: " << model;
                QDBusInterface *iface = new QDBusInterface("com.kylin.dockerAgent", "/com/kylin/dockerAgent", "com.kylin.dockerAgent", QDBusConnection::systemBus());
                if (!iface->isValid())
                {
                    qDebug() << "ERROR - DBus Interface Connection Failed";
                    qDebug() << qPrintable(QDBusConnection::systemBus().lastError().message());
                    iface = nullptr;
                    delete iface;
                    return;
                }
                QDBusReply<bool> res;
                if (model)
                {
                    res = iface->call("updateFile", true, execFile);
                }
                else
                {
                    res = iface->call("updateFile", false, execFile);
                }
                if (!res.isValid())
                {
                    qDebug() << "ERROR - DBus Method Call Failed";
                    iface = nullptr;
                    delete iface;
                    return;
                }
                if (!res.value())
                {
                    qDebug() << "ERROR - DBus Method Exec Failed";
                    iface = nullptr;
                    delete iface;
                    return;
                }
                if (iface)
                {
                    iface = nullptr;
                    delete iface;
                }
                if (!selectedOption.isEmpty())
                {
                    QProcess *process = new QProcess;
                    QString main_ = main;
                    main_ += " ";
                    main_ += selectedOption;
                    main_ += " rightclick";
                    qDebug() << "DEBUG - Main " << main_;
                    process->start(main_);
                    if (!process->waitForStarted())
                    {
                        qDebug() << "ERROR - 兼容模式不能启动";
                        process->kill();
                        process = nullptr;
                        delete process;
                        return;
                    }
                }
                else
                {
                    QMessageBox::warning(nullptr, "警告", "请选择兼容环境", QMessageBox::Ok);
                    return;
                }
            });
            actions << dirAction;
        }
    }
    return actions;
}
