/*
   
        (c) 2006 by Thomas Michel <tom.michel@arcor.de>

        Kwlan is free software; you can redistribute it and/or modify
        it under the terms of the GNU Library General Public License as
        published by the Free Software Foundation; either version 2 of
        the License, or (at your option) any later version.

        Kwlan 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 Library General Public License for more details.

        You should have received a copy of the GNU Library General Public License
        along with this library; see the file COPYING.LIB.  If not, write to
        the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
        Boston, MA 02110-1301, USA.
*/

#include "dialupclass.h"
#include "globals.h"
#include "kwlansuprocess.h"

#include <QString>
#include <QFile>
#include <kmessagebox.h>
#include <klocale.h>
#include <qregexp.h>
#include <kdebug.h>
#include <pwd.h>
#include <k3process.h>

dialupClass::dialupClass(QObject *parent, const char *name): 
          QObject(parent)
{
    if (parent) parent->setObjectName(name);
}

dialupClass::~dialupClass()
{
}


bool dialupClass::readData(QString profile)
{
    if (profile.isEmpty()) return FALSE;

    QString filename = QString(PPP_PEERS) + QString("/") + profile;
    QFile confFile(filename);
    if ( confFile.open( QIODevice::ReadOnly) ) {
        QTextStream stream( &confFile );
        QString line;
        
        while ( !stream.atEnd() ) {
            line = stream.readLine();
            parseConfigLine(line);
        }
        confFile.close();
    }
    else {
        KMessageBox::sorry(0,i18n("Could not read connection settings. Maybe you do not have access to them?"));
        return FALSE;
    }
    return TRUE;
}

bool dialupClass::writeData(QString profile)
{
    uid_t uid;
    QString user;
    struct passwd *pw;
    uid = geteuid ();
    pw = getpwuid (uid);
    if (pw)
    {
        user = QString(pw->pw_name);
    }
    else 
    {
        KMessageBox::sorry(0,i18n("Could not find out your username. Cannot store the connection."));
        return false;
    }
    QString filename = QString(PPP_PEERS) + QString("/") + profile;
    QFile *dialupFile = new QFile(filename);
    QString number, config;
    if (dialupFile->open(QIODevice::WriteOnly))
    {
        QTextStream stream( dialupFile );
        switch (m_data.connectionType)
        {
            case dialupData::ISDN:
                stream << "plugin capiplugin.so\n";
                stream << "protocol hdlc\n";
                stream << "sync\n";
                number = QString("number %1\n").arg(m_data.number);
                stream << number.toLatin1();
                break;
            case dialupData::PPPOE:
                stream << QString("plugin rp-pppoe.so %1\n").arg(m_data.interface);
                break;
            case dialupData::ANALOG:
                if (m_data.initString.isEmpty())
                {
                    config =QString("connect \"/usr/sbin/chat -v '' ATZ OK-AT-OK ATDT%1 CONNECT \\d\\c\"\n").arg(m_data.number);
                    stream << config.toLatin1();
                }
                else {
                    config =QString("connect \"/usr/sbin/chat -v '' ATZ OK-AT-OK %1 OK ").arg(m_data.initString);
                    config += QString("ATDT%1 CONNECT \\d\\c\"\n").arg(m_data.number);
                    stream << config.toLatin1();
                    //stream << QString("#initstring %1\n").arg(m_data.initString.toLatin1());
                    stream << QString("#initstring %1\n").arg(m_data.initString);
                }
                //stream << QString("connect \"/usr/sbin/chat -v '' ATZ OK-AT-OK ATDT%1 CONNECT \\d\\c\"\n").arg(m_data.number);
                stream << QString("%1\n").arg(m_data.interface);
                break;
        }
        stream << QString("user %1\n").arg(m_data.user);
        if (m_data.storepassword)
        {
            stream << QString("#storepassword\n");
            stream << QString("password %1\n").arg(m_data.password);
        }
        if (m_data.noipdefault)
            stream << QString("noipdefault\n");
        if (m_data.defaultroute)
            stream << QString("defaultroute\n");
        if (m_data.noauth)
            stream << QString("noauth\n");
        if (m_data.persist)
            stream << QString("persist\n");
        if (m_data.replacedefaultroute)
            stream << QString("replacedefaultroute\n");
        if (m_data.usepeerdns)
            stream << QString("usepeerdns\n");
        if (m_data.hidepassword)
            stream << QString("hide-password\n");
        stream << QString("#scriptafterconnect %1\n").arg(m_data.scriptAfterConnect);
        stream << QString("#scriptbeforedisconnect %1\n").arg(m_data.scriptBeforeDisconnect);
        if (m_data.scriptAfterConnectRoot)
            stream << QString("#scriptafterconnectroot\n");
        if (m_data.scriptBeforeDisconnectRoot)
            stream << QString("#scriptbeforedisconnectroot\n");
        dialupFile->close();
        //KwlanSuProcess *proc = new KwlanSuProcess();
        K3Process *proc = new K3Process;
        QString command = QString("chmod 600 %1").arg(filename);
        connect(proc, SIGNAL(receivedStdout(K3Process *, char *, int)),this,SLOT(slotWriteProcessWrote(K3Process *, char*,int)));
        *proc << "bash" << "-c" << command;
        connect(proc, SIGNAL(processExited(K3Process *)),this,SLOT(slotWriteProcessExited(K3Process *)));
        proc->start();
        return TRUE;
    } else {
        KMessageBox::sorry(0,i18n("Could not open file %1 for writing.\nMake sure you are in the dip group to have access to /etc/ppp.",filename));
        return FALSE;
    }
}

void dialupClass::parseConfigLine( QString line)
{
    // parses a line from the config file and sets the parameters in data
    //skip leading and trailing spaces
    line = line.trimmed();
    // check for comment
//    if (line.startsWith("#"))
//        return;
    // now split into parameter / value
    QString param, value;
    int index = line.indexOf (' ');
    if (index==-1)
    {
        param = line;
        value = "";
    }
    else {
        param = line.left(index);
        value = line.mid(index);
        value = value.trimmed();
    }
    //now we have the config parameter
    //set connection typ to modem first, as pppoe / isdn contain a plugin parameter
    if (param.toLower()=="plugin")
    {
        if (value.toLower() == "capiplugin.so") m_data.connectionType = dialupData::ISDN;
        else if (value.toLower().startsWith("rp-pppoe.so"))
        {
            m_data.connectionType = dialupData::PPPOE;
            // check the pppoe interface
            index = value.indexOf(' ');
            if (index==-1) kWarning() << "PPPOE plugin has no interface configured." ;
            else m_data.interface = value.mid(index+1);
        }
        return;
    }
    if (param.toLower()=="user")
    {
        if (value.startsWith("\""))
            m_data.user = value.mid(1,value.length()-2);
        else m_data.user= value;
        return;
    }
    if (param.toLower()=="password")
    {
        if (value.startsWith("\""))
            m_data.password = value.mid(1,value.length()-2);
        else m_data.password= value;
        return;
    }
    if (param.toLower()=="number")
        m_data.number = value;
    if (param.toLower().startsWith("/dev"))
        m_data.interface = param;
    if (param.toLower()=="connect")
    {
        //extract phone number from connection string
        QRegExp regExp;
        regExp.setPattern( "ATDT(\\S+)" );
        if ( regExp.indexIn( value ) > -1 )
            m_data.number = regExp.cap( 1 );
    }
    if (param.toLower()=="noipdefault")
    {
        m_data.noipdefault = TRUE;
        return;
    }
    if (param.toLower() == "defaultroute")
    {
        m_data.defaultroute = TRUE;
        return;
    }
    if (param.toLower()=="replacedefaultroute")
    {
        m_data.replacedefaultroute = TRUE;
        return;
    }
    if (param.toLower()=="noauth")
    {
        m_data.noauth = TRUE;
        return;
    }
    if (param.toLower()=="persist")
    {
        m_data.persist = TRUE;
        return;
    }
    if (param.toLower()=="usepeerdns")
    {
        m_data.usepeerdns = TRUE;
        return;
    }
    if (param.toLower()=="hide-password")
    {
        m_data.hidepassword = TRUE;
        return;
    }
    if (param.toLower()=="#scriptbeforedisconnect")
    {
        if (value.startsWith("\""))
            m_data.scriptBeforeDisconnect = value.mid(1,value.length()-2);
        else m_data.scriptBeforeDisconnect= value;
        return;
    }
    if (param.toLower()=="#scriptafterconnect")
    {
        if (debugOutput) kDebug() << "Script after connect "<< value;
        if (value.startsWith("\""))
            m_data.scriptAfterConnect = value.mid(1,value.length()-2);
        else m_data.scriptAfterConnect= value;
        return;
    }
    if (param.toLower()=="#scriptafterconnectroot")
    {
        m_data.scriptAfterConnectRoot = TRUE;
        return;
    }
    if (param.toLower()=="#scriptbeforedisconnectroot")
    {
        m_data.scriptBeforeDisconnectRoot = TRUE;
        return;
    }
    if (param.toLower()=="#storepassword")
    {
        m_data.storepassword = TRUE;
        return;
    }
    if (param.toLower()=="#initstring")
    {
        m_data.initString = value;
        return;
    }

    // kDebug() << "Unknown parameter in peer configuration";
}
void dialupClass::slotWriteProcessExited( K3Process* proc)

{
    if (proc->exitStatus()==0)
        emit dataWritten();
    else KMessageBox::sorry(0,i18n("Could not write connection settings. Maybe you do not have access to them?"));
}

void dialupClass::slotWriteProcessWrote( K3Process* proc,char *buffer, int buflen)
{
    if (!::debugOutput) return;
    QString rawBuffer = QString::fromLocal8Bit( buffer, buflen );
    QStringList lines = rawBuffer.split( QRegExp( "\n|\n\r|\r\n" ));
    QStringList::Iterator it = lines.begin();    
  
    while ( it != lines.end() ) {
        QString curLine = *it;
        kDebug() << curLine;
        it++;
    }
}

#include "dialupclass.moc"
                 
