#include "process/exec_opkg_command.h"
#include "worker.h"
#include "utils_internal.h"

#include <QStringList>

ExecOpkgCommand::ExecOpkgCommand(QString const &command,
                                 Worker *worker,
                                 int nextCommandIndex,
                                 bool noaction,
                                 int start_timeout,
                                 int finish_timeout)
  : UpdateCommand(command, worker, nextCommandIndex, start_timeout, finish_timeout)
  , m_noaction(noaction)
  , m_ok_count{0}
  , m_fail_count{0} {
}

void ExecOpkgCommand::finished(int exitCode, QProcess::ExitStatus exitStatus) {
    QProcess *p = (QProcess *)sender();
    if (p) {
        Worker *w = worker();
        if (w) {
            if (m_fail_count == 0 && m_ok_count > 0) {
                emit w->showExecOpkgOverallResult(internal::EXEC_OPKG_COMMANDS_SUCCESS, m_noaction);
            } else
            if (m_ok_count == 0 && m_fail_count > 0) {
                emit w->showExecOpkgOverallResult(internal::EXEC_OPKG_COMMANDS_FAIL, m_noaction);
            } else {
                // TODO
                emit w->showExecOpkgOverallResult(internal::EXEC_OPKG_COMMANDS_SUCCESS, m_noaction);
            }
        }
    }
    return UpdateCommand::finished(exitCode, exitStatus);
}

void ExecOpkgCommand::readyReadStandardOutput() {
    QProcess *p = (QProcess *)sender();
    if (p) {
        Worker *w = worker();
        if (w) {
            QString s = p->readAllStandardOutput().trimmed();
            if (!s.isEmpty()) {
                m_standardOutput += s.replace(QChar('\n'), "");

                // the command lines in etc/psa_update/opkg_commands are
                // separated by "<OPKG>" markers. Note that the file opkg_commands
                // itself is *not* changed, of course.

                int startIndex, endIndex{};
                while (((startIndex = m_standardOutput.indexOf(internal::OPKG_MARKER)) == 0) &&
                       ((endIndex = m_standardOutput.indexOf(internal::OPKG_MARKER, 1)) != -1)) {

                    QString result = m_standardOutput.mid(0, endIndex).mid(6);
                    m_standardOutput = m_standardOutput.mid(endIndex);

                    if (!s.isEmpty()) {
                        QStringList const lst = result.split(u' ', QString::SkipEmptyParts);

                        if (lst.size() >= 2) {
                            if (lst.last() == "ok") {
                                m_ok_count += 1;
                                if (lst.contains("noaction")) {
                                    emit w->showExecOpkgCommand(result);
                                } else {
                                    emit w->showExecOpkgCommand(result);
                                }
                            } else {
                                m_fail_count += 1;
                                if (lst.contains("noaction")) {
                                    emit w->showExecOpkgCommand(result);
                                } else {
                                    emit w->showExecOpkgCommand(result);
                                }
                            }
                        } else {
                            emit w->showExecOpkgCommand(result);
                        }
                    }
                }
            }
        }
    }
}