/* This file is part of the KDE project
   Copyright (C) 2007 - 2011 Dag Andersen <danders@get2net.dk>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/
// clazy:excludeall=qstring-arg
#include "SchedulerTester.h"

#include "PlanTJPlugin.h"

#include "kptcommand.h"
#include "kptcalendar.h"
#include "kptdatetime.h"
#include "kptresource.h"
#include "kptnode.h"
#include "kpttask.h"
#include "kptschedule.h"
#include "kptxmlloaderobject.h"

#include <QTest>

#include "tests/DateTimeTester.h"

#include "tests/debug.cpp"

namespace KPlato
{

QStringList SchedulerTester::data()
{
    return QStringList()
            << "test1.plan"
            << "startnotearlier.plan"
            ;
}

void SchedulerTester::test()
{
    QString dir = QFINDTESTDATA("data/");
    foreach (const QString &fname, data()) {
        qDebug()<<"Testing file:"<<fname;
        QFile file(dir + fname);
        QVERIFY2(file.open(QIODevice::ReadOnly), fname.toLatin1());

        KoXmlDocument doc;
        QString error;
        bool setContent;
        int line, column;
        if (! (setContent = doc.setContent(&file, &error, &line, &column))) {
            file.close();
            QString s = QString("%1: %2 Line %3, column %4").arg(fname).arg(error).arg(line).arg(column);
            QVERIFY2(setContent, s.toLatin1());
        }
        file.close();

        testProject(fname, doc);
    }
}

void SchedulerTester::testProject(const QString &fname, const KoXmlDocument &doc)
{
    
    KoXmlElement pel = doc.documentElement().namedItem("project").toElement();
    if (pel.isNull()) {
        QString s = QString("%1: Cannot find 'project' element").arg(fname);
        QVERIFY2(!pel.isNull(), s.toLatin1());
    }
    Project project;
    project.setTimeZone(QTimeZone("UTC"));

    XMLLoaderObject status;
    status.setProject(&project);
    status.setVersion(doc.documentElement().attribute("version", PLAN_FILE_SYNTAX_VERSION));
    bool projectLoad = project.load(pel, status);
    if (! projectLoad) {
        QString s = QString("%1: Failed to load project").arg(fname);
        QVERIFY2(projectLoad, s.toLatin1());        
    }
    QString s = project.description();
    if (! s.isEmpty()) {
        qDebug();
        qDebug()<<project.description();
        qDebug();
    }

    ScheduleManager *manager = project.scheduleManagers().value(0);
    s = QString("%1: No schedule to compare with").arg(fname);
    QVERIFY2(manager, s.toLatin1());

    ScheduleManager *sm = project.createScheduleManager("Test Plan");
    project.addScheduleManager(sm);

    PlanTJPlugin tj(0, QVariantList());
qDebug() << "+++++++++++++++++++++++++++calculate-start";
    tj.calculate(project, sm, true/*nothread*/);
qDebug() << "+++++++++++++++++++++++++++calculate-end";
    
    s = QString("%1: Scheduling failed").arg(fname);
    QVERIFY2(sm->calculationResult() == ScheduleManager::CalculationDone, s.toLatin1());

    long id1 = manager->scheduleId();
    long id2 = sm->scheduleId();
    qDebug()<<project.startTime(id1)<<project.startTime(id2)<<project.timeZone();
    s = QString("%1: Compare project schedules:\n Expected: %2\n   Result: %3")
            .arg(fname)
            .arg(project.startTime(id1).toString(Qt::ISODate))
            .arg(project.startTime(id2).toString(Qt::ISODate));
    QVERIFY2(project.startTime(id1) == project.startTime(id2), s.toLatin1()); 
    
    foreach (Node *n, project.allNodes()) {
        compare(fname, n, id1, id2);
    }
}

void SchedulerTester::compare(const QString &fname, Node *n, long id1, long id2)
{
    QString s = QString("%1: '%2' Compare task schedules:\n Expected: %3\n   Result: %4").arg(fname).arg(n->name());
    QVERIFY2(n->startTime(id1) == n->startTime(id2), (s.arg(n->startTime(id1).toString(Qt::ISODate)).arg(n->startTime(id2).toString(Qt::ISODate))).toLatin1());
    QVERIFY2(n->endTime(id1) == n->endTime(id2), (s.arg(n->endTime(id1).toString(Qt::ISODate)).arg(n->endTime(id2).toString(Qt::ISODate))).toLatin1());
}

} //namespace KPlato

QTEST_GUILESS_MAIN(KPlato::SchedulerTester)
