//-*-c++-*-
/***************************************************************************
 *   Copyright (C) 2003 by Fred Schaettgen                                 *
 *   kbluetoothd@schaettgen.de                                             *
 *   Derived from kinetd, (C) 2002 by Tim Jansen <tim@tjansen.de>
 *                                                                         *
 *   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.                                   *
 ***************************************************************************/

#include "metaserver.h"
#include <qregexp.h>
#include <kservicetype.h>
#include <kdebug.h>
#include <kconfig.h>
#include <klocale.h>
#include <kglobal.h>
#include <kprocess.h>
#include <kmessagebox.h>
#include <ksystemtray.h>
#include <qtimer.h>
#include <kapplication.h>

#include "rfcommportlistener.h"
#include <libkbluetooth/deviceaddress.h>
#include <libkbluetooth/adapter.h>
#include <kmessagebox.h>
#include <kdialogbase.h>
#include "confirmation.h"

using namespace KBluetooth;

MetaServer::MetaServer(QObject *parent) :
    DCOPObject("MetaServer"), QObject(parent)
{
    m_config = KGlobal::config();
    confirmation = new Confirmation();
    reload();
}

void MetaServer::loadServiceList()
{
    m_portListeners.clear();

    KService::List kbluetoothdModules =
        KServiceType::offers("KBluetoothDModule");
    kdDebug() << "Kbluetoothd: loadServiceList()" << endl;
    for (KService::List::ConstIterator it = kbluetoothdModules.begin();
         it != kbluetoothdModules.end();
         it++)
    {
        KService::Ptr s = *it;
        
        QString sProtocol;
        QVariant vProtocol = s->property("X-KDE-KBLUETOOTHD-protocol");
        if (vProtocol.isValid())
        {
            sProtocol = vProtocol.toString();
        }

        PortListener *pl;
        if (sProtocol == "rfcomm")
        {
            pl = new RfcommPortListener(this, s, m_config);
        }
        else
        {
            kdDebug() << "Kbluetoothd: Could not create listener for "
            << s->name() << ": Unknown protocol ("
            << sProtocol << ")"
            << s->propertyNames().join("|") << endl;
            continue;
        }

        if (pl->isValid())
            m_portListeners.append(pl);
        else
            delete pl;
    }
}


PortListener *MetaServer::getListenerByName(QString name)
{
    PortListener *pl = m_portListeners.first();
    while (pl)
    {
        if (pl->name() == name)
            return pl;
        pl = m_portListeners.next();
    }
    return pl;
}

QStringList MetaServer::services()
{
    QStringList list;
    PortListener *pl = m_portListeners.first();
    while (pl)
    {
        list.append(pl->name());
        pl = m_portListeners.next();
    }
    return list;
}

bool MetaServer::isEnabled(QString service)
{
    PortListener *pl = getListenerByName(service);
    if (!pl)
        return false;

    return pl->isEnabled();
}

void MetaServer::setAuthentication(QString service, bool enable)
{
    PortListener *pl = getListenerByName(service);
    if (!pl) return;
    pl->setAuthentication(enable);  
}

void MetaServer::setEncryption(QString service, bool enable)
{
    PortListener *pl = getListenerByName(service);
    if (!pl) return;
    pl->setEncryption(enable);  
}

bool MetaServer::getAuthentication(QString service)
{
    PortListener *pl = getListenerByName(service);
    if (!pl) return false;
    return pl->getAuthentication();  
}

bool MetaServer::getEncryption(QString service)
{
    PortListener *pl = getListenerByName(service);
    if (!pl) return false;
    return pl->getEncryption();  
}

QStringList MetaServer::resourceTypes(QString service)
{
    PortListener *pl = getListenerByName(service);
    if (!pl) return QStringList();

    return pl->resourceTypes();
}

QString MetaServer::resources(QString service, QString resourceType)
{
    PortListener *pl = getListenerByName(service);
    if (!pl) return QString::null;

    return pl->resource(resourceType);
}

bool MetaServer::isInstalled(QString service)
{
    PortListener *pl = getListenerByName(service);
    return (pl != 0);
}

QString MetaServer::docPath(QString service)
{
    PortListener *pl = getListenerByName(service);
    if (pl) {
        return pl->docPath();
    }
    else {
        return QString::null;
    }
}

QString MetaServer::description(QString service)
{
    PortListener *pl = getListenerByName(service);
    if (pl) {
        return pl->description();
    }
    else {
        return QString::null;
    }
}

void MetaServer::setEnabled(QString service, bool enable)
{
    PortListener *pl = getListenerByName(service);
    if (!pl)
        return;

    pl->setEnabled(enable);
    //setExpirationTimer();
    //setReregistrationTimer();
}

void MetaServer::setServiceRegistrationEnabled(QString service, bool enable)
{
    PortListener *pl = getListenerByName(service);
    if (!pl)
        return;

    pl->setServiceRegistrationEnabled(enable);
    //setReregistrationTimer();
}

bool MetaServer::isServiceRegistrationEnabled(QString service)
{
    PortListener *pl = getListenerByName(service);
    if (!pl)
        return false;

    return pl->isServiceRegistrationEnabled();
}

/*QStringList MetaServer::customizedDevices()
{
    return Confirmation::getCustomizedDevices(m_config);
}


int MetaServer::connectPermissionSetting(
    QString deviceaddress, QString servicename)
{
    return Confirmation::getPermissionSetting(m_config,
        KBluetooth::DeviceAddress(deviceaddress), servicename);
}


void MetaServer::setConnectPermissionSetting(QString deviceaddress,
    QString servicename, int setting)
{
    Confirmation::setPermissionSetting(m_config,
        KBluetooth::DeviceAddress(deviceaddress), servicename,
        Confirmation::PermissionSetting(setting));
}*/

int MetaServer::numConnectionRules()
{
    return confirmation->getNumRules();
}

QString MetaServer::getRuleAddress(int ruleNumber)
{
    return QString(confirmation->getRule(ruleNumber).addr);
}

QString MetaServer::getRuleService(int ruleNumber)
{
    return confirmation->getRule(ruleNumber).service;
}

QString MetaServer::getRulePolicy(int ruleNumber)
{
    return confirmation->getRule(ruleNumber).policy;
}

bool MetaServer::insertConnectionRule(int ruleNumber, QString addr, 
    QString service, QString policy)
{
    Confirmation::ConnectionRule rule;
    if (addr == "*") {
        rule.addr = DeviceAddress::any;
    } 
    else {
        rule.addr = DeviceAddress(addr);
    }
    rule.service = service;
    rule.policy = policy;
    confirmation->insertRule(ruleNumber, rule);
    return true;
}

bool MetaServer::deleteConnectionRule(int ruleNumber)
{
    return confirmation->deleteRule(ruleNumber);
}

QStringList MetaServer::getRulePolicyList()
{
    return confirmation->getPolicies();
}

void MetaServer::reload()
{
    m_portListeners.setAutoDelete(false);
    while (m_portListeners.count() > 0) {
        delete m_portListeners.first();
        m_portListeners.removeFirst();
    }
    m_config->sync();
    m_config->reparseConfiguration();
    loadServiceList();
}

bool MetaServer::canConfigure(QString service)
{
    PortListener *listener = getListenerByName(service);
    if (listener) {
        return listener->canConfigure();
    }
    else return false;
}

void MetaServer::configure(QString service)
{
    PortListener *listener = getListenerByName(service);
    if (listener) {
        listener->configure();
    }
}

MetaServer::~MetaServer()
{
    while (m_portListeners.count() > 0) {
        delete m_portListeners.first();
        m_portListeners.removeFirst();
    }
}

#include "metaserver.moc"
