#include "agent.hpp"
#include <QtDebug>
#include <QStringList>
#include <string>
#include "qlog.hpp"
#include <QFile>

Agent::Agent()
{
    qInstallMessageHandler(myMessageOutput);
}
Agent::~Agent()
{
}

int Agent::dockerAgentTest()
{
    return 1024;
}

int Agent::dockerAgentCreate(const QString uid, const QString name, const QString env,
                             const QString sharedDir, const QString image)
{
    dockerLaunchCmd = "docker create -u ";
    dockerLaunchCmd = dockerLaunchCmd + uid + " -it --name " + name + " " + env + " " + sharedDir + " " + image;
    qDebug() << "DEBUG - dockerAgentCreateCmd: " << dockerLaunchCmd;
    QProcess proc;
    proc.start(dockerLaunchCmd);
    if (!proc.waitForStarted())
    {
        qDebug() << "ERROR - dockerAgentCreate 启动失败";
        return -1;
    }
    if (!proc.waitForFinished(1000 * 5))
    {
        qDebug() << "ERROR - dockerAgentCreate 执行超时";
        return -404;
    }
    if (proc.exitCode() != 0)
    {
        qDebug() << "ERROR - dockerAgentCreate 执行失败";
        return -1;
    }
    qDebug() << "DEBUG - dockerAgentCreate 执行成功";
    return 0;
}
int Agent::dockerAgentCp(const QString src, const QString des)
{
    dockerLaunchCmd = "docker cp ";
    dockerLaunchCmd = dockerLaunchCmd + src + " " + des;
    qDebug() << "DEBUG - dockerAgentCpCmd: " << dockerLaunchCmd;
    QProcess proc;
    proc.start(dockerLaunchCmd);
    if (!proc.waitForStarted())
    {
        qDebug() << "ERROR - dockerAgentCp 启动失败";
        return -1;
    }
    if (!proc.waitForFinished(1000 * 30))
    {
        qDebug() << "ERROR - dockerAgentCp 执行超时";
        return -404;
    }
    if (proc.exitCode() != 0)
    {
        qDebug() << "ERROR - dockerAgentCp 执行失败";
        return -1;
    }
    qDebug() << "DEBUG - dockerAgentCp 执行成功";
    return 0;
}
int Agent::dockerAgentInspect(const QString name)
{
    dockerLaunchCmd = "docker inspect ";
    dockerLaunchCmd = dockerLaunchCmd + name;
    qDebug() << "DEBUG - dockerAgentInspectCmd: " << dockerLaunchCmd;
    QProcess proc;
    proc.start(dockerLaunchCmd);
    if (!proc.waitForStarted())
    {
        qDebug() << "ERROR - dockerAgentInspect 启动失败";
        return -1;
    }
    if (!proc.waitForFinished(1000 * 5))
    {
        qDebug() << "ERROR - dockerAgentInspect 执行超时";
        return -404;
    }
    if (proc.exitCode() != 0)
    {
        qDebug() << "WARNING - dockerAgentInspect 执行成功，容器" << name << "不存在";
        return -2;
    }
    qDebug() << "DEBUG - dockerAgentInspect 执行成功";
    return 0;
}
int Agent::dockerAgentRm(const QString name)
{
    dockerLaunchCmd = "docker rm -f ";
    dockerLaunchCmd = dockerLaunchCmd + name;
    qDebug() << "DEBUG - dockerAgentRmCmd: " << dockerLaunchCmd;
    QProcess proc;
    proc.start(dockerLaunchCmd);
    if (!proc.waitForStarted())
    {
        qDebug() << "ERROR - dockerAgentRm 启动失败";
        return -1;
    }
    if (!proc.waitForFinished(1000 * 5))
    {
        qDebug() << "ERROR - dockerAgentRm 执行超时";
        return -404;
    }
    if (proc.exitCode() != 0)
    {
        qDebug() << "ERROR - dockerAgentRm 执行失败";
        return -1;
    }
    qDebug() << "DEBUG - dockerAgentRm 执行成功";
    return 0;
}
int Agent::dockerAgentStart(const QString name)
{
    dockerLaunchCmd = "docker start ";
    dockerLaunchCmd = dockerLaunchCmd + name;
    qDebug() << "DEBUG - dockerAgentStartCmd: " << dockerLaunchCmd;
    QProcess proc;
    proc.start(dockerLaunchCmd);
    if (!proc.waitForStarted())
    {
        qDebug() << "ERROR - dockerAgentStart 启动失败";
        return -1;
    }
    if (!proc.waitForFinished(1000 * 5))
    {
        qDebug() << "ERROR - dockerAgentStart 执行超时";
        return -404;
    }
    if (proc.exitCode() != 0)
    {
        qDebug() << "ERROR - dockerAgentStart 执行失败";
        return -1;
    }
    qDebug() << "DEBUG - dockerAgentStart 执行成功";
    return 0;
}
int Agent::dockerAgentExec(const QString name, const QString cmd)
{
    std::string name_ = name.toStdString();
    std::string cmd_ = cmd.toStdString();
    std::string dockerLaunchCmd_ = "docker exec " + name_ + " /bin/bash -c \"" + cmd_ + "\"";
    qDebug() << "DEBUG - dockerAgentExecCmd: " << QString(dockerLaunchCmd_.data());
    int ret = system(dockerLaunchCmd_.data());
    if (1 == ret)
    {
        qDebug() << "ERROR - " << QString("程序命令为空");
        return -1;
    }
    else if (-1 == ret)
    {
        qDebug() << "ERROR - " << QString("创建命令子进程失败");
        return -1;
    }
    else if (0x7f00 == ret)
    {
        qDebug() << "ERROR - " << QString("命令错误，无法执行");
        return -1;
    }
    else
    {
        if (WIFEXITED(ret))
        {
            if (WEXITSTATUS(ret) != 0)
            {
                qDebug() << "ERROR - " << QString("程序异常结束，返回值：%1").arg(WEXITSTATUS(ret));
                return -1;
            }
        }
        else if (WIFSIGNALED(ret))
        {
            qDebug() << "ERROR - " << QString("程序被信号杀死，信号值：%1").arg(WTERMSIG(ret));
            return -1;
        }
        else if (WSTOPSIG(ret))
        {
            qDebug() << "ERROR - " << QString("程序被信号暂停，信号值：%1").arg(WSTOPSIG(ret));
            return -1;
        }
    }
    qDebug() << "DEBUG - dockerAgentExec 执行成功";
    return 0;
}
int Agent::dockerAgentRun(const QString name, const QString cmd)
{
    std::string name_ = name.toStdString();
    std::string cmd_ = cmd.toStdString();
    std::string dockerLaunchCmd_ = "docker exec " + name_ + " /bin/bash -c \"" + cmd_ + "\"";
    qDebug() << "DEBUG - dockerAgentRunCmd: " << QString(dockerLaunchCmd_.data());
    FILE *pF = popen(dockerLaunchCmd_.data(), "r");
    if (pF == NULL)
    {
        qDebug() << "ERROR - dockerAgentRun 执行失败";
        return -1;
    }
    qDebug() << "DEBUG - dockerAgentRun 执行成功";
    // 程序不能阻塞，需要注释掉下面这行
    // pclose(pF);
    return 0;
}
QString Agent::dockerAgentPs()
{
    dockerLaunchCmd = "docker ps -a";
    QProcess process;
    process.start(dockerLaunchCmd);
    process.waitForFinished();
    int exitCode = process.exitCode();
    if (process.exitCode() != 0)
    {
        qDebug() << "ERROR - dockerAgentPs 执行失败，exitCode: " << exitCode;
        return "";
    }
    QByteArray data = process.readAllStandardOutput();
    QString output = QString::fromUtf8(data);
    qDebug() << "DEBUG - dockerAgentPs 返回值为:" << output;
    qDebug() << "DEBUG - dockerAgentPs 执行成功";
    return output;
}
bool Agent::updateFile(bool flag, const QString file)
{
    QFile qf(file);
    if (!qf.exists())
    {
        qDebug() << "ERROR - " << file << " Not Exists";
        return false;
    }
    QString fileTmp = file;

    fileTmp.remove("KARE");
    QString fileBAK = fileTmp + "_BAK";
    QString fileKAREBAK = fileTmp + "_KAREBAK";

    QFile qf2;
    if (!qf2.exists(fileBAK) || !qf2.exists(fileKAREBAK))
    {
        qDebug() << "ERROR - " << fileBAK << " or " << fileKAREBAK << " Not Exists";
        return false;
    }

    std::string file_ = file.toStdString();
    std::string fileBAK_ = fileBAK.toStdString();
    std::string fileKAREBAK_ = fileKAREBAK.toStdString();
    std::string updateCmd = "";
    if (flag)
    {
        updateCmd = "cp -fp " + fileKAREBAK_ + " " + file_;
    }
    else
    {
        updateCmd = "cp -fp " + fileBAK_ + " " + file_;
    }
    qDebug() << "DEBUG - updateCmd: " << QString(updateCmd.data());
    int ret = system(updateCmd.data());
    if (1 == ret)
    {
        qDebug() << "ERROR - " << QString("程序命令为空");
        return false;
    }
    else if (-1 == ret)
    {
        qDebug() << "ERROR - " << QString("创建命令子进程失败");
        return false;
    }
    else if (0x7f00 == ret)
    {
        qDebug() << "ERROR - " << QString("命令错误，无法执行");
        return false;
    }
    else
    {
        if (WIFEXITED(ret))
        {
            if (WEXITSTATUS(ret) != 0)
            {
                qDebug() << "ERROR - " << QString("程序异常结束，返回值：%1").arg(WEXITSTATUS(ret));
                return false;
            }
        }
        else if (WIFSIGNALED(ret))
        {
            qDebug() << "ERROR - " << QString("程序被信号杀死，信号值：%1").arg(WTERMSIG(ret));
            return false;
        }
        else if (WSTOPSIG(ret))
        {
            qDebug() << "ERROR - " << QString("程序被信号暂停，信号值：%1").arg(WSTOPSIG(ret));
            return false;
        }
    }
    qDebug() << "DEBUG - updateFile 执行成功";
    return true;
}
