/*
* Copyright (C) 2010 Daniele E. Domenichelli <daniele.domenichelli@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "test-accept-file-transfer.h"
#include <KTelepathy/AcceptFileTransferJob>
#include <KTelepathy/TelepathyBridge>

extern "C"
{
#include <signal.h>
}

#include <KAboutData>
#include <KCmdLineArgs>
#include <KDebug>
#include <KApplication>
#include <KNotification>
#include <kio/global.h>
#include <kjobtrackerinterface.h>

#include <Nepomuk/ResourceManager>
#include <TelepathyQt4/Channel>
#include <TelepathyQt4/ClientRegistrar>
#include <TelepathyQt4/Account>
#include <TelepathyQt4/Debug>

namespace
{
    static void signal_handler(int signal)
    {
        if ((signal == SIGTERM) || (signal == SIGINT)) {
            QCoreApplication * const app(QCoreApplication::instance());
            if (app != 0) {
                kDebug() << "Signal Handler Called. Exiting...";
                app->quit();
            }
        }
    }
}

int main(int argc, char** argv)
{
    KAboutData aboutData("file-transfer-receiver", 0, ki18n("Test AcceptFileTransfer"), "0.1");

    KCmdLineArgs::init(argc, argv, &aboutData);
    KApplication app;

    Nepomuk::ResourceManager::instance()->init();

    // Set up signal handlers.
    if (signal(SIGINT, signal_handler) == SIG_ERR) {
        kWarning() << "Setting up SIGINT signal handler failed.";
    }

    if (signal(SIGTERM, signal_handler) == SIG_ERR) {
        kWarning() << "Setting up SIGTERM signal handler failed.";
    }

    //Enable telepathy-Qt4 debug
    Tp::enableDebug(true);
    Tp::enableWarnings(true);

//    Test::AcceptFileTransfer* receiver = new Test::AcceptFileTransfer(0);
    Tp::SharedPtr<Test::AcceptFileTransfer> receiver = Tp::SharedPtr<Test::AcceptFileTransfer>(new Test::AcceptFileTransfer(0));

    Tp::ClientRegistrarPtr registrar = Tp::ClientRegistrar::create();
    registrar->registerClient(Tp::AbstractClientPtr::dynamicCast(receiver), "telepathy_test_accept_file_transfer");

    receiver->show();

    // Start event loop.
    return app.exec();
}

namespace Test {

static inline Tp::ChannelClassList channelClassList()
{
    QMap<QString, QDBusVariant> filter0;
    filter0[TELEPATHY_INTERFACE_CHANNEL ".ChannelType"] =
            QDBusVariant(TELEPATHY_INTERFACE_CHANNEL_TYPE_FILE_TRANSFER);
    filter0[TELEPATHY_INTERFACE_CHANNEL ".Requested"] = QDBusVariant(false);
    filter0[TELEPATHY_INTERFACE_CHANNEL ".TargetHandleType"] = QDBusVariant(1);

    return Tp::ChannelClassList() << Tp::ChannelClass(filter0);
}

AcceptFileTransfer::AcceptFileTransfer(QWidget* parent)
    : QDialog(parent),
      Tp::AbstractClientHandler(channelClassList(), false)
{
    kDebug();
/*
    // Check if Nepomuk Query service client is up and running
    if (!Nepomuk::Query::QueryServiceClient::serviceAvailable()) {
        // That's a failure
        KMessageBox::error(this, i18n("The Nepomuk Query Service client is not available on your system. "
                                      "Contactlist requires the query service client to be available: please "
                                      "check your system settings"));
    }
*/

    setupUi(this);
    // Initialize Telepathy
    KTelepathy::TelepathyBridge::instance()->init();
//    connect(TelepathyBridge::instance(),
//            SIGNAL(ready(bool)),
//            SLOT(onHandlerReady(bool)));

/*
    // Get 'me' as soon as possible
    // FIXME: Port to new OSCAF standard for accessing "me" as soon as it
    // becomes available.
    Nepomuk::Thing me(QUrl::fromEncoded("nepomuk:/myself"));


    // Loop through all the grounding instances of this person
    foreach (Nepomuk::InformationElement resource, me.groundingOccurrences()) {
        // See if this grounding instance is of type nco:contact.
        if (resource.hasType(Nepomuk::Vocabulary::NCO::PersonContact())) {
            // FIXME: We are going to assume the first NCO::PersonContact is the
            // right one. Can we improve this?
            m_mePersonContact = resource;
            break;
        }
    }
*/


//    Tp::enableDebug(true);
//    Tp::enableWarnings(true);

    /* Registering telepathy types */
    Tp::registerTypes();
}


AcceptFileTransfer::~AcceptFileTransfer()
{
    kDebug();
}

bool AcceptFileTransfer::bypassApproval() const
{
    kDebug() << "bypassing";
    return false;
}

void AcceptFileTransfer::handleChannels(const Tp::MethodInvocationContextPtr<> & context,
        const Tp::AccountPtr & account,
        const Tp::ConnectionPtr & connection,
        const QList<Tp::ChannelPtr> & channels,
        const QList<Tp::ChannelRequestPtr> & requestsSatisfied,
        const QDateTime & userActionTime,
        const QVariantMap & handlerInfo)
{
    Q_UNUSED(account);
    Q_UNUSED(connection);
    Q_UNUSED(requestsSatisfied);
    Q_UNUSED(userActionTime);
    Q_UNUSED(handlerInfo);

    foreach(const Tp::ChannelPtr &channel, channels) {
        kDebug() << "Handling new file transfer";

        QVariantMap properties = channel->immutableProperties();
        kDebug() << properties;


        if (properties[TELEPATHY_INTERFACE_CHANNEL ".ChannelType"] == TELEPATHY_INTERFACE_CHANNEL_TYPE_FILE_TRANSFER) {
            kDebug() << "Handling:" << TELEPATHY_INTERFACE_CHANNEL_TYPE_FILE_TRANSFER;

            m_contactLineEdit->setText(properties[TELEPATHY_INTERFACE_CHANNEL ".InitiatorID"].toString());
            m_origFilenameLineEdit->setText(properties[TELEPATHY_INTERFACE_CHANNEL_TYPE_FILE_TRANSFER ".Filename"].toString());
            m_filenameUrlRequester->setText(QDir::homePath() + "/Downloads/" + properties[TELEPATHY_INTERFACE_CHANNEL_TYPE_FILE_TRANSFER ".Filename"].toString());
            m_filenameUrlRequester->setEnabled(true);
            m_channel = channel;
            connect (m_acceptPushButton, SIGNAL(clicked(bool)),
                     this, SLOT(onAcceptClicked(void)));
            m_acceptPushButton->setEnabled(true);
        }
    }
    context->setFinished();
}

void AcceptFileTransfer::asyncCall(KJob* job)
{
    kDebug();
    connect( job,  SIGNAL(result(KJob*)),
             this, SLOT  (handleResult(KJob*)));
    job->start();
}


void AcceptFileTransfer::handleResult(KJob * job)
{
    if ( job->error() ) {
        kError() << "Error during file transfer:" << job->errorString();
        return;
    }

    KTelepathy::AcceptFileTransferJob* acceptFileTransferJob = dynamic_cast<KTelepathy::AcceptFileTransferJob*>(job);
    if(!acceptFileTransferJob) {
        // Not an OfferFileTransferJob
        return;
    }
    m_contactLineEdit->setText("");
    m_origFilenameLineEdit->setText("");
    m_filenameUrlRequester->setText("");
    m_filenameUrlRequester->setEnabled(false);
}


void AcceptFileTransfer::syncCall(KJob* job)
{
    if ( !job->exec() ) {
        kError() << "Error during file transfer:" << job->errorString();
        return;
    } else {
        KTelepathy::AcceptFileTransferJob* acceptFileTransferJob = dynamic_cast<KTelepathy::AcceptFileTransferJob*>(job);
        if(!acceptFileTransferJob) {
            // Not an OfferFileTransferJob
            return;
    }
    m_contactLineEdit->setText("");
    m_origFilenameLineEdit->setText("");
    m_filenameUrlRequester->setText("");
    m_filenameUrlRequester->setEnabled(false);
    }
}


void AcceptFileTransfer::onInfoMessage(KJob* job, const QString &plain, const QString &rich)
{
    Q_UNUSED(job)
    Q_UNUSED(rich)
    kDebug() << plain;

//    KNotification::event("newAcceptFileTransferEvent", plain, rich);
}


void AcceptFileTransfer::onAcceptClicked(void)
{
    KJob* job  = KTelepathy::TelepathyBridge::instance()->acceptFileTransfer(m_channel, m_filenameUrlRequester->text());

    if (job) {
        connect (job,  SIGNAL(infoMessage(KJob*,QString,QString)),
                 this, SLOT(onInfoMessage(KJob*,QString,QString)));

    KIO::getJobTracker()->registerJob(job);

    if (m_acceptComboBox->currentIndex() == 0)
        asyncCall(job);
    else
        syncCall(job);
    }
}


} // end namespace Test
