/*
 * Copyright (C) 2020, 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/>.
 */
#include <stdio.h>

#include <QString>
#include <QDomDocument>
#include <QDomElement>
#include <QDomNode>
#include <QFile>
#include <QDebug>
#include <QFileInfo>
#include "lib_fun.h"
#include <QProcess>

#define XML_APPLICATIONS_PATH "/opt/kre/config/applications_v2.xml"
#define CMD_DPKG "dpkg -S %s | awk -F':' '{print $1}'"

/*
 * compatible environment analysis pkgname and runtime by desktop field
 * p_desktop_path_in --> desktop ptah -> in , p_pkg_name_out --> analysis pkg_name -> out , analysis runtime -> out
 * return 0->success , -1->fail
 */
int snow_analysis_xml(const QString &p_desktop_path_in , QString &p_pkg_name_out , QString &p_runtime_out)
{
    if (p_desktop_path_in.isEmpty()) {
        qWarning() << "Error : args error";
        return -1;
    }

    QString pkg_name;
    QStringList runtime_list;
    pkg_name.clear();
    runtime_list.clear();

    QString desktop_path(p_desktop_path_in);
    QString desktop_name = desktop_path.split('/').last();

    QString p_buf;

    int index = desktop_name.indexOf("kylin-v10");
    if (index == -1) {
        qWarning() << "Error : desktop name error";
        return -1;
    }

    p_buf = desktop_name.left(index) + desktop_name.mid(index + 8);

    qDebug() << "Info : handle desktop name is [" << p_buf << "]";

    desktop_name = p_buf;

    QDomDocument doc;
    QFile file(XML_APPLICATIONS_PATH);
    if (!file.open(QIODevice::ReadOnly | QFile::Text)) {
        qWarning() << "Error : open xml file fail";
        return -1;
    }

    if (!doc.setContent(&file)) {
        qWarning() << "Error : load xml file fail";
        return -1;
    }
    file.close();

    QDomElement root = doc.documentElement();
    QDomNode first = root.firstChild();

    bool found = false;
    while (!first.isNull()) {
        if (first.nodeName() == "appPkgName") {
            pkg_name = first.toElement().attribute("name");
            QDomNode second = first.firstChild();
            while (!second.isNull()) {
                if (second.nodeName() == "runtimes") {
                    QDomNode third = second.firstChild();
                    while (!third.isNull()) {
                        if (third.nodeName() == "runtime") {
                            runtime_list << third.toElement().text();
                        }
                        third = third.nextSibling();
                    }
                }
                if (second.nodeName() == "appEntrys" && second.toElement().attribute("desktop") == desktop_name) {
                    found = true;
                    break;
                }
                second = second.nextSibling();
            }
        }
        if (found) break;
        first = first.nextSibling();
    }

    if (found) {
        p_pkg_name_out = pkg_name;
        if (!runtime_list.isEmpty()) {
            p_runtime_out = runtime_list.at(0);
        }
        return 0;
    }

    qWarning() << "Error : not analysis desktop";
    return -1;
}



QString get_zhname(QString p_desktop_path_in)
{
    QSettings setting(p_desktop_path_in, QSettings::IniFormat);
    QString locale = getenv("LANG");
    setting.beginGroup("Desktop Entry");

    if (locale.contains("zh_CN")) {
        if (setting.allKeys().contains("Name[zh_CN]")) {
            return QString(setting.value("Name[zh_CN]").toString().toLatin1());
        }
        else
        {
            return QString(setting.value("Name").toString().toLatin1());
        }
    }
    return QString(setting.value("Name").toString().toLatin1());
}

/*
 * get local pkgname by desktop
 * return 0->success , -1->fail
 */
QString snow_get_local_pkg_name(QString p_desktop_path_in)
{
    if (p_desktop_path_in.length() <= 0) {
        printf("Error : arg error\n");
        return QString(); // 返回空字符串
    }

    QFileInfo filein(p_desktop_path_in);
    QString fileffsufix = filein.suffix();
    if (!fileffsufix.contains("desktop", Qt::CaseSensitive)) {
        return QString(); // 返回空字符串
    }

    if (p_desktop_path_in.contains("TopSAP")) {
        return "topsap";
    }

    QString cmd;
    cmd.append("dpkg -S ").append(p_desktop_path_in).append(" | awk -F':' '{print $1}'");
    QString pkgname = SelectPackgeName(cmd);
    if (pkgname.isEmpty()) {
        // 寻找包名，只按desktop文件寻找并不完全准确。
        QFile file(p_desktop_path_in);
        if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            while (!file.atEnd()) {
                QByteArray line = file.readLine();
                QString str(line);
                if (str.contains("Exec", Qt::CaseSensitive)) {
                    QStringList list = str.split("=");
                    if (list.size() > 1) { // 检查list的大小
                        if (list[1].contains("/usr/bin/runWithCompatibility.sh") || list[1].contains("kare run")) {
                            pkgname = "kare";
                            return pkgname;
                        }
                        if (list[1].contains(" ", Qt::CaseSensitive)) {
                            QStringList desk_one = list[1].split(" ");
                            cmd.clear();
                            cmd.append("dpkg -S ").append(desk_one[0]).append(" | awk -F':' '{print $1}'");
                            pkgname = SelectPackgeName(cmd);
                            return pkgname;
                        } else {
                            cmd.clear();
                            cmd.append("dpkg -S ").append(list[1].simplified()).append(" | awk -F':' '{print $1}'");
                            pkgname = SelectPackgeName(cmd);
                            return pkgname;
                        }
                    }
                }
            }
        } else {
            printf("Error: Unable to open file\n");
            return QString(); // 返回空字符串
        }
    } else {
        return pkgname;
    }

    return QString(); // 默认返回空字符串
}

QString SelectPackgeName(QString cmd)
{
    QProcess terminal;
    QStringList cmdList;
    cmdList << "-c" << cmd;
    terminal.start("/bin/bash",cmdList);
    terminal.waitForFinished();

    QString debInfo = terminal.readAll();
    return debInfo.simplified();
}



QString getAndroidPackageName(QString desktopFilePath)
{
    if (desktopFilePath == NULL) {
        return NULL;
    }
    if(desktopFilePath.contains("TopSAP"))
    {
        return  "topsap";
    }
    QString androidFilePath(desktopFilePath);
    QString desktopFileName = androidFilePath.split('/').last();
    return QString(desktopFileName.mid(0, desktopFileName.count() - 8).toLatin1().data());

}

QString getKarePackageNameFromFile(const QString &filePath)
{
    QProcess process;
    process.start("kare",QStringList()<<"-S"<<filePath);
    process.waitForFinished();

    QString output = process.readAllStandardOutput();
    QString error = process.readAllStandardError();
    if (!error.isEmpty())
    {
        qWarning()<<"lib_fun::getKarePackageNameFromFile::error="<<error;
        return QString();
    }

    QStringList lines = output.split('\n');
    for (const QString &line: lines)
    {
        int colonIndex = line.indexOf(':');
        if (colonIndex != -1)
        {
            QString packageName = line.left(colonIndex).trimmed();
            if (!packageName.isEmpty())
            {
                return packageName;
            }
        }

    }
    qWarning() << "lib_fun::getKarePackageNameFromFile::output="<<output;
    return QString();

}

/*
 * remove line last ernter
 */
void remove_last_line_break(QString &src_in_out)
{
    if (src_in_out.endsWith('\n')) {
        src_in_out.chop(1);
    }
}


/*
 * get max six chinese characters from char array
 */
QString intercept_chinese_characters(QString src_in)
{
    QString dst;
    dst.clear();
    int i_len = src_in.length();
    qDebug() << "==========" << i_len;

    if (i_len > 6) {
        dst = src_in.mid(0 , 6);
    } else {
        dst = src_in;
    }

    qDebug() << "---------->" << dst;

    return dst;
}
