/*
   
        (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 Steet, Fifth Floor,
        Boston, MA 02110-1301, USA.
*/

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

#include <qstring.h>
#include <qfile.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <qregexp.h>
#include <kdebug.h>
#include <pwd.h>
#include <kprocess.h>

dialupClass::dialupClass(QObject *parent, const char *name): 
  QObject(parent, 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( IO_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 don't have access to it?"));
        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(IO_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.latin1();
                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.latin1();
                }
                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.latin1();
                    stream << QString("#initstring %1\n").arg(m_data.initString.latin1());
                }
                //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();
        KProcess *proc = new KProcess;
        QString command = QString("chown %1:%2 %3 && chmod 600 %4").arg(user,user,filename,filename);
        connect(proc, SIGNAL(receivedStdout(KProcess *, char *, int)),this,SLOT(slotWriteProcessWrote(KProcess *, char*,int)));
        *proc << "bash" << "-c" << command;
        connect(proc, SIGNAL(processExited(KProcess *)),this,SLOT(slotWriteProcessExited(KProcess *)));
        proc->start();
        
        return TRUE;
    } else {
        KMessageBox::sorry(0,QString(i18n("Could not open file %1 for writing.\n Make sure you are in the dip group to have access to /etc/ppp.")).arg(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.stripWhiteSpace();
    // check for comment
//    if (line.startsWith("#"))
//        return;
    // now split into parameter / value
    QString param, value;
    int index = line.find (' ');
    if (index==-1)
    {
        param = line;
        value = "";
    }
    else {
        param = line.left(index);
        value = line.mid(index);
        value = value.stripWhiteSpace();
    }
    //now we have the config parameter
    //set connection typ to modem first, as pppoe / isdn contain a plugin parameter
    if (param.lower()=="plugin")
    {
        if (value.lower() == "capiplugin.so") m_data.connectionType = dialupData::ISDN;
        else if (value.lower().startsWith("rp-pppoe.so"))
        {
            m_data.connectionType = dialupData::PPPOE;
            // check the pppoe interface
            index = value.find(' ');
            if (index==-1) kdWarning() << "PPPOE plugin has no interface configured." << endl;
            else m_data.interface = value.mid(index+1);
        }
        return;
    }
    if (param.lower()=="user")
    {
        if (value.startsWith("\""))
            m_data.user = value.mid(1,value.length()-2);
        else m_data.user= value;
        return;
    }
    if (param.lower()=="password")
    {
        if (value.startsWith("\""))
            m_data.password = value.mid(1,value.length()-2);
        else m_data.password= value;
        return;
    }
    if (param.lower()=="number")
        m_data.number = value;
    if (param.lower().startsWith("/dev"))
        m_data.interface = param;
    if (param.lower()=="connect")
    {
        //extract phone number from connection string
        QRegExp regExp;
        regExp.setPattern( "ATDT(\\S+)" );
        if ( regExp.search( value ) > -1 )
            m_data.number = regExp.cap( 1 );
    }
    if (param.lower()=="noipdefault")
    {
        m_data.noipdefault = TRUE;
        return;
    }
    if (param.lower() == "defaultroute")
    {
        m_data.defaultroute = TRUE;
        return;
    }
    if (param.lower()=="replacedefaultroute")
    {
        m_data.replacedefaultroute = TRUE;
        return;
    }
    if (param.lower()=="noauth")
    {
        m_data.noauth = TRUE;
        return;
    }
    if (param.lower()=="persist")
    {
        m_data.persist = TRUE;
        return;
    }
    if (param.lower()=="usepeerdns")
    {
        m_data.usepeerdns = TRUE;
        return;
    }
    if (param.lower()=="hide-password")
    {
        m_data.hidepassword = TRUE;
        return;
    }
    if (param.lower()=="#scriptbeforedisconnect")
    {
        if (value.startsWith("\""))
            m_data.scriptBeforeDisconnect = value.mid(1,value.length()-2);
        else m_data.scriptBeforeDisconnect= value;
        return;
    }
    if (param.lower()=="#scriptafterconnect")
    {
        if (debugOutput) kdDebug() << "Script after connect "<< value << endl;
        if (value.startsWith("\""))
            m_data.scriptAfterConnect = value.mid(1,value.length()-2);
        else m_data.scriptAfterConnect= value;
        return;
    }
    if (param.lower()=="#scriptafterconnectroot")
    {
        m_data.scriptAfterConnectRoot = TRUE;
        return;
    }
    if (param.lower()=="#scriptbeforedisconnectroot")
    {
        m_data.scriptBeforeDisconnectRoot = TRUE;
        return;
    }
    if (param.lower()=="#storepassword")
    {
        m_data.storepassword = TRUE;
        return;
    }
    if (param.lower()=="#initstring")
    {
        m_data.initString = value;
        return;
    }

    // kdDebug() << "Unknown parameter in peer configuration" << endl;
}
void dialupClass::slotWriteProcessExited( KProcess* proc)

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

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