/***************************************************************************
   Copyright (c) 2004 Kevin Ottens <ervin ipsquad net>
   Rearranged by Marco Gulino <marco@kmobiletools.org> for the mobile protocol

   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 "mobile.h"

#include <q3cstring.h>
#include <q3socket.h>
#include <qdatetime.h>
#include <qbitarray.h>

#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include "deviceIFace_stub.h"

#include <kapplication.h>
#include <kdebug.h>
#include <kmessagebox.h>
#include <kinstance.h>
#include <kglobal.h>
#include <kstandarddirs.h>
#include <klocale.h>
#include <kurl.h>
#include <ksock.h>
#include <kmobiletools_devices.h>

using namespace KIO;


kio_mobileProtocol::kio_mobileProtocol(const Q3CString &pool_socket, const Q3CString &app_socket)
    : SlaveBase("kio_mobile", pool_socket, app_socket)
{
    kDebug() <<"kio_mobileProtocol::kio_mobileProtocol()";
    m_dcop.attach();
}


kio_mobileProtocol::~kio_mobileProtocol()
{
    kDebug() <<"kio_mobileProtocol::~kio_mobileProtocol()";
}

// From here, it's copied and adapted from kdebase/kioslave/system
void kio_mobileProtocol::listDir(const KUrl &url)
{
    kDebug() <<"MobileProtocol::listDir:" << url;

    if ( url.path().length() <= 1 )
    {
        listRoot();
        return;
    }
    QString host=QStringList::split("/",url.path() ).first();
    KMobileTools::DevicesConfig *hostCFG=KMobileTools::DevicesConfig::prefs(host);
    hostCFG->readConfig();
    kDebug() <<"Reading config";
    kDebug() <<"FSType:" << hostCFG->fstype();
    KUrl target;
    switch( hostCFG->fstype() ){
        case 1:
            kDebug() <<"P2K Filesystem";
            target.setProtocol("p2k");
            target.setUser( host);
            target.setHost(QString("%1.%2")
                    .arg(hostCFG->p2k_vendor())
                    .arg(hostCFG->p2k_prodid()) );
            break;
        case 2:
            kDebug() <<"ObexFTP Filesystem";
            target.setProtocol("obex2");
            switch( hostCFG->obex_transp() ){
                case 0:
                    target.setHost( "irda"); break;
                case 1:
                    target.setHost("inet"); break;
                case 2:
                    target.setHost("custom"); break;
                case 3:
                default:
                    target.setHost("bluetooth"); break;
                case 4:
                    target.setHost("usb"); break;
            }
            kDebug() <<"Obex transport:" << hostCFG->obex_transp() <<"; device:" << hostCFG->obex_device() <<"; port:" << hostCFG->obex_port();
            target.setUser(hostCFG->obex_device().replace("/", "\\") );
            if(hostCFG->obex_port()) target.setPort(hostCFG->obex_port());
            break;
    }
    kDebug() <<"Resulting URL: \"" << target <<"\"; is valid:" << target.isValid();
//     target.setProtocol("p2k");
//     target.setHost(host);
//     kDebug() <<"Path:" << url.path() <<"; host:" << url.host();
//     kDebug() <<"possible redirection target :" << target;
    if( target.isValid() )
    {
        DeviceIFace_stub dcopDevice(&m_dcop, Q3CString("kmobiletools"), host.utf8() );
        kDebug() <<"launching switch2filesystem() to `" << dcopDevice.app() <<"` -- `" << dcopDevice.obj() <<"`";
        dcopDevice.switch2filesystem();
        kDebug() <<"Call failed:" << (dcopDevice.status() == DCOPStub::CallFailed);
        redirection(target);
        finished();
        return;
    }

    error(KIO::ERR_MALFORMED_URL, url.prettyUrl());
}

void kio_mobileProtocol::stat(const KUrl &url)
{
    kDebug() <<"MobileProtocol::stat:" << url;

    QString path = url.path();
    if ( path.isEmpty() || path == "/" )
    {
                // The root is "virtual" - it's not a single physical directory
        KIO::UDSEntry entry;
        m_impl.createTopLevelEntry( entry );
        statEntry( entry );
        finished();
        return;
    }


//     error(KIO::ERR_MALFORMED_URL, url.prettyUrl());
}


void kio_mobileProtocol::listRoot()
{
    KIO::UDSEntry entry;

    KIO::UDSEntryList mobile_entries;
    bool ok = m_impl.listRoot(mobile_entries);

    if (!ok)
    {
        error( m_impl.lastErrorCode(), m_impl.lastErrorMessage() );
        return;
    }

    totalSize(mobile_entries.count()+1);

    m_impl.createTopLevelEntry(entry);
    listEntry(entry, false);

    KIO::UDSEntryListIterator it = mobile_entries.begin();
    KIO::UDSEntryListIterator end = mobile_entries.end();

    for(; it!=end; ++it)
    {
        listEntry(*it, false);
    }

    entry.clear();
    listEntry(entry, true);

    finished();
}

// end of the system kioslave part

extern "C"
{
    int kdemain(int argc, char **argv)
    {
        KInstance instance( "kio_mobile" );
        
        kDebug(7101) <<"*** Starting kio_mobile";
        
        if (argc != 4) {
            kDebug(7101) <<"Usage: kio_mobile  protocol domain-socket1 domain-socket2";
            exit(-1);
        }
        
        kio_mobileProtocol slave(argv[2], argv[3]);
        slave.dispatchLoop();
        
        kDebug(7101) <<"*** kio_mobile Done";
        return 0;
    }
} 
