/*
   Copyright (C) 2014-2020 Laurent Montel <montel@kde.org>

   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; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#include "createtodojob.h"
#include "createtodoplugin_debug.h"
#include <Akonadi/KMime/MessageParts>
#include <AkonadiCore/ItemFetchJob>
#include <AkonadiCore/ItemFetchScope>
#include <AkonadiCore/ItemCreateJob>
#include <AkonadiCore/RelationCreateJob>

#include <KMime/Message>

using namespace MessageViewer;

CreateTodoJob::CreateTodoJob(const KCalendarCore::Todo::Ptr &todoPtr, const Akonadi::Collection &collection, const Akonadi::Item &item, QObject *parent)
    : KJob(parent)
    , mItem(item)
    , mCollection(collection)
    , mTodoPtr(todoPtr)
{
}

CreateTodoJob::~CreateTodoJob()
{
    qCDebug(CREATETODOPLUGIN_LOG) << " CreateTodoJob::~CreateTodoJob()";
}

void CreateTodoJob::start()
{
    // We need the full payload to attach the mail to the incidence
    if (!mItem.loadedPayloadParts().contains(Akonadi::MessagePart::Body)) {
        Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob(mItem);
        job->fetchScope().fetchFullPayload();
        connect(job, &Akonadi::ItemFetchJob::result, this, &CreateTodoJob::slotFetchDone);
    } else {
        createTodo();
    }
}

void CreateTodoJob::slotFetchDone(KJob *job)
{
    Akonadi::ItemFetchJob *fetchJob = qobject_cast<Akonadi::ItemFetchJob *>(job);
    if (fetchJob->items().count() == 1) {
        mItem = fetchJob->items().at(0);
    } else {
        qCDebug(CREATETODOPLUGIN_LOG) << " createTodo Error during fetch: " << job->errorString();
        emitResult();
        return;
    }
    createTodo();
}

void CreateTodoJob::createTodo()
{
    if (!mItem.hasPayload<KMime::Message::Ptr>()) {
        qCDebug(CREATETODOPLUGIN_LOG) << " item has not payload";
        emitResult();
        return;
    }

    Akonadi::Item newTodoItem;
    newTodoItem.setMimeType(KCalendarCore::Todo::todoMimeType());
    newTodoItem.setPayload<KCalendarCore::Todo::Ptr>(mTodoPtr);

    Akonadi::ItemCreateJob *createJob = new Akonadi::ItemCreateJob(newTodoItem, mCollection);
    connect(createJob, &Akonadi::ItemCreateJob::result, this, &CreateTodoJob::todoCreated);
}

void CreateTodoJob::todoCreated(KJob *job)
{
    if (job->error()) {
        qCDebug(CREATETODOPLUGIN_LOG) << "Error during create new Todo " << job->errorString();
        setError(job->error());
        setErrorText(job->errorText());
        emitResult();
    } else {
        Akonadi::ItemCreateJob *createJob = static_cast<Akonadi::ItemCreateJob *>(job);
        Akonadi::Relation relation(Akonadi::Relation::GENERIC, mItem, createJob->item());
        Akonadi::RelationCreateJob *rJob = new Akonadi::RelationCreateJob(relation);
        connect(rJob, &Akonadi::RelationCreateJob::result, this, &CreateTodoJob::relationCreated);
    }
}

void CreateTodoJob::relationCreated(KJob *job)
{
    if (job->error()) {
        qCDebug(CREATETODOPLUGIN_LOG) << "Error during create new Todo " << job->errorString();
    }
    emitResult();
}
