/* This file is part of the KDE project
   SPDX-FileCopyrightText: 2012 Dag Andersen <dag.andersen@kdemail.net>

   SPDX-License-Identifier: LGPL-2.0-or-later
*/
// clazy:excludeall=qstring-arg
#include "WorkPackageProxyModelTester.h"
#include "kptcommand.h"
#include "kpttask.h"
#include "kptnode.h"
#include "kptnodeitemmodel.h"

#include <QModelIndex>

#include <QTest>

#include "../../kernel/tests/debug.cpp"

namespace KPlato
{

Task *WorkPackageProxyModelTester::addTask(Node *parent, int after)
{
    Task *task = project.createTask();
    TaskAddCmd cmd(&project, task, parent->childNode(after));
    cmd.redo();
    ResourceRequest *rr = new ResourceRequest(project.resourceGroupAt(0)->resourceAt(0), 100);
    AddResourceRequestCmd c2(&task->requests(), rr);
    c2.redo();
    return task;
}

void WorkPackageProxyModelTester::removeTask(Node *task)
{
    NodeDeleteCmd cmd(task);
    cmd.redo();
}

void WorkPackageProxyModelTester::moveTask(Node *task, Node *newParent, int newPos)
{
    NodeMoveCmd cmd(&project, task, newParent, newPos);
    cmd.redo();
}

void WorkPackageProxyModelTester::initTestCase()
{
    project.setName("P1");
    project.setId(project.uniqueNodeId());
    project.registerNodeId(&project);
    Calendar *calendar = new Calendar();
    calendar->setName("C1");
    calendar->setDefault(true);
    QTime t1(9, 0, 0);
    QTime t2 (17, 0, 0);
    int length = t1.msecsTo(t2);
    for (int i=1; i <= 7; ++i) {
        CalendarDay *d = calendar->weekday(i);
        d->setState(CalendarDay::Working);
        d->addInterval(t1, length);
    }
    project.addCalendar(calendar);

    QCOMPARE(m_model.rowCount(), 0);
    m_model.setProject(&project);
    QCOMPARE(m_model.rowCount(), 0);

    ResourceGroup *g = new ResourceGroup();
    g->setName("G1");
    project.addResourceGroup(g);
    Resource *r = new Resource();
    r->setName("R1");
    project.addResource(r);
    g->addResource(r);

    sm = project.createScheduleManager();
    m_model.setScheduleManager(sm);
}

void WorkPackageProxyModelTester::testInsert()
{
    Task *task = addTask(&project, 0);
    task->setName("T1");
    QCOMPARE(m_model.baseModel()->rowCount(), 1);
    QCOMPARE(m_model.rowCount(), 0); // filtered, (not scheduled)

    sm->createSchedules();
    project.calculate(*sm);
    QVERIFY(task->isScheduled());
    QCOMPARE(m_model.rowCount(), 1);
    QCOMPARE(m_model.index(0, NodeModel::NodeName).data().toString(), QString("T1"));

    task = addTask(&project, -1);
    task->setName("T2");
    QCOMPARE(m_model.baseModel()->rowCount(), 2);
    QCOMPARE(m_model.rowCount(), 1); // filtered, (not scheduled)
    sm->createSchedules();
    project.calculate(*sm);
    QVERIFY(task->isScheduled());
    QCOMPARE(m_model.rowCount(), 2);
    QCOMPARE(m_model.index(1, NodeModel::NodeName).data().toString(), QString("T2"));

    task = addTask(&project, -1);
    task->setName("T3");
    QCOMPARE(m_model.baseModel()->rowCount(), 3);
    QCOMPARE(m_model.rowCount(), 2); // filtered, (not scheduled)
    sm->createSchedules();
    project.calculate(*sm);
    QVERIFY(task->isScheduled());
    QCOMPARE(m_model.rowCount(), 3);
    QCOMPARE(m_model.index(2, NodeModel::NodeName).data().toString(), QString("T3"));
}

void WorkPackageProxyModelTester::testRemove()
{

    removeTask(project.childNode(0));
    QCOMPARE(m_model.rowCount(), 2);
    QCOMPARE(m_model.index(0, NodeModel::NodeName).data().toString(), QString("T2"));
    QCOMPARE(m_model.index(1, NodeModel::NodeName).data().toString(), QString("T3"));

    removeTask(project.childNode(1));
    QCOMPARE(m_model.rowCount(), 1);
    QCOMPARE(m_model.index(0, NodeModel::NodeName).data().toString(), QString("T2"));

    removeTask(project.childNode(0));
    QCOMPARE(m_model.rowCount(), 0);
}

void WorkPackageProxyModelTester::testMove()
{
    testInsert();
    //Debug::print(&project, "T1, T2, T3 ---------", true);
    moveTask(project.childNode(0), &project, 1);
    //Debug::print(&project, "T2, T1, T3 ---------", true);
    QCOMPARE(m_model.rowCount(), 3);
    QCOMPARE(m_model.index(0, NodeModel::NodeName).data().toString(), QString("T2"));
    QCOMPARE(m_model.index(1, NodeModel::NodeName).data().toString(), QString("T1"));
    QCOMPARE(m_model.index(2, NodeModel::NodeName).data().toString(), QString("T3"));

    moveTask(project.childNode(1), &project, 0);
    QCOMPARE(m_model.index(0, NodeModel::NodeName).data().toString(), QString("T1"));
    QCOMPARE(m_model.index(1, NodeModel::NodeName).data().toString(), QString("T2"));
    QCOMPARE(m_model.index(2, NodeModel::NodeName).data().toString(), QString("T3"));

    moveTask(project.childNode(1), &project, 0);
    QCOMPARE(m_model.index(0, NodeModel::NodeName).data().toString(), QString("T2"));
    QCOMPARE(m_model.index(1, NodeModel::NodeName).data().toString(), QString("T1"));
    QCOMPARE(m_model.index(2, NodeModel::NodeName).data().toString(), QString("T3"));

    moveTask(project.childNode(0), &project, -1); // last
    QCOMPARE(m_model.index(0, NodeModel::NodeName).data().toString(), QString("T1"));
    QCOMPARE(m_model.index(1, NodeModel::NodeName).data().toString(), QString("T3"));
    QCOMPARE(m_model.index(2, NodeModel::NodeName).data().toString(), QString("T2"));
}

void WorkPackageProxyModelTester::testMoveChild()
{
    while (project.numChildren() > 0) {
        Node *t = project.childNode(0);
        project.takeTask(t);
        delete t;
    }
    testInsert();
    Task *task = addTask(&project, 1); // after 1 = 2 :(
    task->setName("T4");
    //Debug::print(&project, "T1, T2, T4, T3 ----", true);
    QCOMPARE(project.numChildren(), 4);
    QCOMPARE(m_model.rowCount(), 3); // filtered, (not scheduled)

    sm->createSchedules();
    project.calculate(*sm);
    //Debug::print(&project, "T1, T2, T4, T3 ----", true);
    QVERIFY(task->isScheduled());
    QCOMPARE(m_model.rowCount(), 4);
    QCOMPARE(m_model.index(0, NodeModel::NodeName).data().toString(), QString("T1"));
    QCOMPARE(m_model.index(1, NodeModel::NodeName).data().toString(), QString("T2"));
    QCOMPARE(m_model.index(2, NodeModel::NodeName).data().toString(), QString("T4"));
    QCOMPARE(m_model.index(3, NodeModel::NodeName).data().toString(), QString("T3"));

    project.indentTask(project.childNode(2));
    //Debug::print(&project, "T1, T2 -> T4, T3 ----", true);
    QCOMPARE(m_model.rowCount(), 3);
    QCOMPARE(m_model.index(0, NodeModel::NodeName).data().toString(), QString("T1"));
    QCOMPARE(m_model.index(1, NodeModel::NodeName).data().toString(), QString("T4"));
    QCOMPARE(m_model.index(2, NodeModel::NodeName).data().toString(), QString("T3"));

    moveTask(project.childNode(1)->childNode(0), project.childNode(0), 0);
    //Debug::print(&project, "T1 -> T4, T2, T3 ----", true);
    QCOMPARE(m_model.rowCount(), 3);
    QCOMPARE(m_model.index(0, NodeModel::NodeName).data().toString(), QString("T4"));
    QCOMPARE(m_model.index(1, NodeModel::NodeName).data().toString(), QString("T2"));
    QCOMPARE(m_model.index(2, NodeModel::NodeName).data().toString(), QString("T3"));

    moveTask(project.childNode(0)->childNode(0), project.childNode(2), 0);
    //Debug::print(&project, "T1, T2, T3 -> T4 ----", true);
    QCOMPARE(m_model.rowCount(), 3);
    QCOMPARE(m_model.index(0, NodeModel::NodeName).data().toString(), QString("T1"));
    QCOMPARE(m_model.index(1, NodeModel::NodeName).data().toString(), QString("T2"));
    QCOMPARE(m_model.index(2, NodeModel::NodeName).data().toString(), QString("T4"));

    moveTask(project.childNode(2)->childNode(0), &project, 0);
    //Debug::print(&project, "T4, T1, T2, T3 ----", true);
    QCOMPARE(m_model.rowCount(), 4);
    QCOMPARE(m_model.index(0, NodeModel::NodeName).data().toString(), QString("T4"));
    QCOMPARE(m_model.index(1, NodeModel::NodeName).data().toString(), QString("T1"));
    QCOMPARE(m_model.index(2, NodeModel::NodeName).data().toString(), QString("T2"));
    QCOMPARE(m_model.index(3, NodeModel::NodeName).data().toString(), QString("T3"));
}

} //namespace KPlato

QTEST_GUILESS_MAIN(KPlato::WorkPackageProxyModelTester)
