/*
 * QtTapioca, the Tapioca Qt4 Client Library
 * Copyright (C) 2006 by INdT
 *  @author Andre Moreira Magalhaes <andre.magalhaes@indt.org>
 *
 * 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 Street, Fifth Floor, Boston,
 * MA 02110-1301, USA
 */

#include "config.h"

#include "QtTapioca/ConnectionManagerFactory"
#include "QtTapioca/ConnectionManager"

#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtDBus/QDBusMetaType>
#include <QtTelepathy/Common/BaseTypes>
#include <QtTelepathy/Common/ConnectionPresenceInterfaceTypes>
#include <QtTelepathy/Common/ConnectionCapabilitiesInterfaceTypes>
#include <QtTelepathy/Common/ConnectionAliasingInterfaceTypes>
#include <QtTelepathy/Common/ConnectionTypes>
#include <QtTelepathy/Common/ChannelTextTypes>
#include <QtTelepathy/Common/ChannelStreamedMediaTypes>

using namespace QtTapioca;

ConnectionManagerFactory *ConnectionManagerFactory::s_self = 0;

ConnectionManagerFactory *ConnectionManagerFactory::self()
{
    if (!s_self)
        s_self = new ConnectionManagerFactory();
    return s_self;
}

ConnectionManagerFactory::ConnectionManagerFactory()
    : QObject(0),
      d(0)
{
    registerTypes();
    load();
}

ConnectionManagerFactory::~ConnectionManagerFactory()
{
    s_self = 0;

    ConnectionManager *cm;
    foreach (cm, m_cms) {
        delete cm;
    }
}

const QList<ConnectionManager*> &ConnectionManagerFactory::getAllConnectionManagers() const
{
    return m_cms;
}

QList<ConnectionManager*> ConnectionManagerFactory::getConnectionManagers(const QString &protocol) const
{
    QList<ConnectionManager*> found;
    ConnectionManager *cm;
    foreach (cm, m_cms) {
        if (cm->supports(protocol)) {
            found.append(cm);
        }
    }
    return found;
}

ConnectionManager *ConnectionManagerFactory::getConnectionManager(const QString &protocol) const
{
    ConnectionManager *cm;
    foreach (cm, m_cms) {
        if (cm->supports(protocol)) {
            return cm;
        }
    }
    return 0;
}

ConnectionManager *ConnectionManagerFactory::getConnectionManagerByName(const QString &name) const
{
    ConnectionManager *cm;
    foreach (cm, m_cms) {
        if (cm->name() == name) {
            return cm;
        }
    }
    return 0;
}

void ConnectionManagerFactory::load()
{
    QStringList configDirs;
    char *dataPath = getenv("TELEPATHY_DATA_PATH");
    if (dataPath) {
        QStringList paths = QString(dataPath).split(":");
        QString path;
        foreach (path, paths) {
            configDirs << path + "/managers";
        }
    }
    configDirs << QString(QDir::homePath() + "/.telepathy/managers");
    configDirs << DATADIR "/telepathy/managers";
    configDirs << "/usr/local/share/telepathy/managers";
    configDirs << "/usr/share/telepathy/managers";

    QString dir;
    foreach (dir, configDirs) {
        QDir configDir(dir);
        QString name;
        QString file;
        QStringList files = configDir.entryList(QStringList("*.manager"), QDir::Files);
        foreach (file, files) {
            QString name = file.left(file.indexOf('.'));

            if (!getConnectionManagerByName(name)) {
                ConnectionManager *cm = new ConnectionManager(configDir.path() + "/" + file, name, this);
                m_cms.append(cm);
            }
        }
    }
}

void ConnectionManagerFactory::registerTypes()
{
    static bool registered = false;
    if (!registered) {
        qDBusRegisterMetaType<QVariantMap>();
        qDBusRegisterMetaType<org::freedesktop::Telepathy::PresenceState>();
        qDBusRegisterMetaType<org::freedesktop::Telepathy::PresenceStateInTime>();
        qDBusRegisterMetaType<org::freedesktop::Telepathy::PresenceStateInTimeMap>();
        qDBusRegisterMetaType<org::freedesktop::Telepathy::CapabilityInfo>();
        qDBusRegisterMetaType<org::freedesktop::Telepathy::CapabilityInfoList>();
        qDBusRegisterMetaType<org::freedesktop::Telepathy::LocalCapabilityInfo>();
        qDBusRegisterMetaType<org::freedesktop::Telepathy::LocalCapabilityInfoList>();
        qDBusRegisterMetaType<org::freedesktop::Telepathy::CapabilitiesChangedInfo>();
        qDBusRegisterMetaType<org::freedesktop::Telepathy::CapabilitiesChangedInfoList>();
        qDBusRegisterMetaType<org::freedesktop::Telepathy::Aliases>();
        qDBusRegisterMetaType<org::freedesktop::Telepathy::AliasInfo>();
        qDBusRegisterMetaType<org::freedesktop::Telepathy::AliasInfoList>();
        qDBusRegisterMetaType<org::freedesktop::Telepathy::ChannelInfo>();
        qDBusRegisterMetaType<org::freedesktop::Telepathy::ChannelInfoList>();
        qDBusRegisterMetaType<org::freedesktop::Telepathy::TextMessageInfo>();
        qDBusRegisterMetaType<org::freedesktop::Telepathy::TextMessageInfoList>();
        qDBusRegisterMetaType<org::freedesktop::Telepathy::StreamInfo>();
        qDBusRegisterMetaType<org::freedesktop::Telepathy::StreamInfoList>();
        registered = true;
    }
}

