/***************************************************************************
 *   Copyright (C) 2008  Tom Patzig <tpatzig@suse.de>                      *
 *   Copyright (C) 2008  Alex Fiestas <alex@eyeos.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; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
 ***************************************************************************/

#include "wizardagent.h"

#include <QDebug>
#include <kstandarddirs.h>
#include "../kbluetoothutils.h"

WizardAgent::WizardAgent(QApplication* application) : QDBusAbstractAdaptor(application)
{
    qDebug() << "AGENT registered !";
    Solid::Control::BluetoothManager &btmanager(Solid::Control::BluetoothManager::self());
    m_iface = new Solid::Control::BluetoothInterface(btmanager.defaultInterface());
}

WizardAgent::~WizardAgent()
{
    qDebug() << "Agent deleted";
}

void WizardAgent::Release()
{
    qDebug() << "Agent Release";
    //TODO: emit a signal
}

void WizardAgent::Authorize(QDBusObjectPath device, const QString& uuid, const QDBusMessage &msg)
{
    Q_UNUSED(device);
    Q_UNUSED(uuid);
    Q_UNUSED(msg);
    qDebug() << "AGENT-Authorize " << device.path() << " Service: " << uuid;
//  QDBusMessage error = msg.createErrorReply("org.bluez.Error.Canceled", "Authorization canceled");
//  QDBusConnection::systemBus().send(error);
}

QString WizardAgent::RequestPinCode(QDBusObjectPath device, const QDBusMessage &msg)
{
    Q_UNUSED(device);
    Q_UNUSED(msg);
    qDebug() << "AGENT-RequestPinCode " << device.path();

    QString pin = getPin(device.path());
    emit pinRequested(pin);
    return QString(pin);
}

quint32 WizardAgent::RequestPasskey(QDBusObjectPath device, const QDBusMessage &msg)
{
    Q_UNUSED(device);
    Q_UNUSED(msg);
    qDebug() << "AGENT-RequestPasskey " << device.path();
    return 0;
}

void WizardAgent::DisplayPasskey(QDBusObjectPath device, quint32 passkey)
{
    Q_UNUSED(device);
    Q_UNUSED(passkey);
    qDebug() << "AGENT-DisplayPasskey " << device.path() << ", " << QString::number(passkey);
}

void WizardAgent::RequestConfirmation(QDBusObjectPath device, quint32 passkey, const QDBusMessage &msg)
{
    Q_UNUSED(device);
    Q_UNUSED(passkey);
    Q_UNUSED(msg);
    qDebug() << "AGENT-RequestConfirmation " << device.path() << ", " << QString::number(passkey);
}

void WizardAgent::ConfirmModeChange(const QString& mode, const QDBusMessage &msg)
{
    Q_UNUSED(mode);
    Q_UNUSED(msg);
    qDebug() << "AGENT-ConfirmModeChange " << mode;
}

void WizardAgent::Cancel()
{
    qDebug() << "AGENT-Cancel";
}

void WizardAgent::setManualPin(const QString& pin)
{
    m_pin = pin;
}

QString WizardAgent::getPin(const QString& path) const
{
    if(!m_pin.isEmpty()) {
        return m_pin;
    }

    QString xmlPath = KStandardDirs::locate("appdata", "pin-code-database.xml");
    Solid::Control::BluetoothRemoteDevice *dev = m_iface->findBluetoothRemoteDeviceUBI(path);

    QFile *file = new QFile(xmlPath);
    if(!file->open(QIODevice::ReadOnly)) {
        qDebug() << "Can't open the device";
        return "";
    }

    QXmlStreamReader* m_xml = new QXmlStreamReader(file);

    int deviceType = dev->getProperties()["Class"].toInt();
    int xmlType = 0;
    QString pin;

    while(!m_xml->atEnd()) {
        m_xml->readNext();
        if(m_xml->name() != "device") {
            continue;
        }
        QXmlStreamAttributes attr = m_xml->attributes();

        if(attr.count() == 0) {
            continue;
        }

        if(attr.hasAttribute("type") && attr.value("type") != "any") {
            xmlType = KBluetoothUtils::stringToType(attr.value("type").toString());
            if(deviceType != xmlType) {
                xmlType = 0; //This is not needed but I like restart the bucle in each interation
                continue;
            }
        }

        if(attr.hasAttribute("oui")) {
            if(!dev->address().startsWith(attr.value("oui").toString())) {
                continue;
            }
        }

        if(attr.hasAttribute("name")) {
            if(dev->name() != attr.value("name").toString()) {
                continue;
            }
        }

        return attr.value("pin").toString();
    }

    if(pin.isEmpty()) {
        return QString("0000");
    }
}