/**
 * UGENE - Integrated Bioinformatics Tools.
 * Copyright (C) 2008-2024 UniPro <ugene@unipro.ru>
 * http://ugene.net
 *
 * 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 2
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 */

#include "DnaAssemblyMultiTask.h"

#include <QMainWindow>
#include <QMessageBox>

#include <U2Algorithm/DnaAssemblyAlgRegistry.h>

#include <U2Core/AppContext.h>
#include <U2Core/L10n.h>
#include <U2Core/ProjectModel.h>

#include <U2Gui/MainWindow.h>
#include <U2Gui/OpenViewTask.h>

namespace U2 {

DnaAssemblyMultiTask::DnaAssemblyMultiTask(const DnaAssemblyToRefTaskSettings& s, bool view, bool _justBuildIndex)
    : ExternalToolSupportTask("DnaAssemblyMultiTask", TaskFlags_NR_FOSE_COSC | TaskFlag_ReportingIsSupported | TaskFlag_ReportingIsEnabled), settings(s),
      assemblyToRefTask(nullptr), shortReadSets(s.shortReadSets), openView(view), justBuildIndex(_justBuildIndex) {
}

void DnaAssemblyMultiTask::prepare() {
    // perform assembly
    QString algName = settings.algName;
    DnaAssemblyAlgorithmEnv* env = AppContext::getDnaAssemblyAlgRegistry()->getAlgorithm(algName);
    if (env == nullptr) {
        setError(QString("Algorithm %1 is not found").arg(algName));
        return;
    }
    assemblyToRefTask = env->getTaskFactory()->createTaskInstance(settings, justBuildIndex);
    assemblyToRefTask->addListeners(getListeners());
    addSubTask(assemblyToRefTask);
}

Task::ReportResult DnaAssemblyMultiTask::report() {
    return ReportResult_Finished;
}

QList<Task*> DnaAssemblyMultiTask::onSubTaskFinished(Task* subTask) {
    QList<Task*> subTasks;
    if (subTask->hasError() || isCanceled()) {
        return subTasks;
    }

    if (subTask == assemblyToRefTask) {
        qint64 time = (subTask->getTimeInfo().finishTime - subTask->getTimeInfo().startTime);
        taskLog.details(QString("Align to reference task time: %1").arg((double)time / (1000 * 1000)));
    }

    if (subTask == assemblyToRefTask && settings.openView) {
        if (assemblyToRefTask->hasResult()) {
            Task* openTask = AppContext::getProjectLoader()->openWithProjectTask(settings.resultFileName);
            if (openTask != nullptr) {
                subTasks << openTask;
            }
        } else {
            QString message = tr("The short reads can't be mapped to the reference sequence!");
            coreLog.info(message);
            if (AppContext::getMainWindow() != nullptr) {
                QMessageBox::information(AppContext::getMainWindow()->getQMainWindow(), L10N::warningTitle(), message);
            }
        }
    }

    return subTasks;
}

QString DnaAssemblyMultiTask::generateReport() const {
    QString res;
    if (hasError()) {
        return QString("Alignment task finished with error: %1").arg(getError());
    }

    if (justBuildIndex) {
        res = settings.algName + QString(" index-file for %1 was built successfully")
                                     .arg(settings.refSeqUrl.fileName());
    } else if (assemblyToRefTask->hasResult()) {
        res = QString("Alignment to reference %1 was finished successfully")
                  .arg(settings.refSeqUrl.fileName());
    } else {
        res = QString("Alignment to reference %1 was failed. No possible alignment was found")
                  .arg(settings.refSeqUrl.fileName());
    }
    return res;
}

}  // namespace U2
