/* This file is part of the KDE project
   Copyright (C) 2002 Alexander Neundorf <neundorf@kde.org>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

   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
   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., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*/

#include "smbmounterplugin.h"

#include <kmessagebox.h>
#include <konq_dirpart.h>
#include <kgenericfactory.h>
#include <kurl.h>
#include <kshortcut.h>
#include <kdebug.h>
#include <kaction.h>

#include <qdir.h>

SmbmounterPlugin::SmbmounterPlugin(QObject* parent, const char* name, const QStringList& )
:KParts::Plugin(parent, name)
{
   //I don't think we have to check for "shell access" here, if a "kiosk" admin
   //doesn't want to provide samba network access, he simply can delete
   //the smb.protocol file, Alex

   m_smbmountAction=new KAction( i18n( "Smb&mount Current Share" ), KShortcut::null(), this,
                SLOT( smbmount() ), actionCollection(), "smbmount" );
   m_smbumountAction=new KAction( i18n( "Smb&umount Current Share" ), KShortcut::null(), this,
                SLOT( smbumount() ), actionCollection(), "smbumount" );

   KonqDirPart * part = parentPart();
   if ( part )
      connect(part,SIGNAL(aboutToOpenURL()),this,SLOT(updateActions()));

   m_smbumountAction->setEnabled(false);
   m_smbmountAction->setEnabled(false);
}

KonqDirPart* SmbmounterPlugin::parentPart() const
{
   // Don't use dynamic_cast in a plugin
   if ( !parent() || !parent()->inherits ( "KonqDirPart" ) )
   {
      kdError() << "SmbmounterPlugin ctor: Program error, please report a bug." << endl;
      return 0L;
   }
   return static_cast<KonqDirPart*>( parent() );
}

void SmbmounterPlugin::updateActions()
{
   KonqDirPart * part = parentPart();
   if ( !part )
      return;
   KURL url=part->url();
   if (url.protocol()!="smb")
      return;

   QString host, share;
   getHostAndShare(url,host,share);
   QString path=buildMountPath(host,share);

   bool shareNotEmpty=!share.isEmpty();
   m_smbumountAction->setEnabled(isMounted(path) && (shareNotEmpty));
   m_smbmountAction->setEnabled(!isMounted(path) && (shareNotEmpty));
}

void SmbmounterPlugin::smbmount()
{
   KonqDirPart * part = parentPart();
   if ( !part )
      return;
   KURL url=part->url();

   getHostAndShare(url,m_host,m_share);
   m_path=buildMountPath(m_host,m_share);

   KURL dummyUrl("smb://dummy");
   QByteArray data;
   QDataStream s(data,IO_WriteOnly);
   int cmd=3;  //3 is mounting with mkdir
   s<<cmd;
   QString tmp="\\\\";
   tmp+=m_host+"/";
   tmp+=m_share;
   s<<tmp;
   s<<m_path;
   tmp="";
   s<<tmp;   //no user
   s<<tmp;   //no password

   KIO::SimpleJob *mountJob=KIO::special(dummyUrl, data, false);
   m_smbumountAction->setEnabled(false);
   m_smbmountAction->setEnabled(false);
   connect( mountJob, SIGNAL( result( KIO::Job * ) ), SLOT( mountResult( KIO::Job * ) ) );
}

void SmbmounterPlugin::smbumount()
{
   KonqDirPart * part = parentPart();
   if ( !part )
      return;

   KURL url=part->url();

   getHostAndShare(url,m_host,m_share);
   m_path=buildMountPath(m_host,m_share);

   KURL dummyUrl("smb://dummy");
   QByteArray data;
   QDataStream s(data,IO_WriteOnly);
   int cmd=4;  //4 is umounting with rmdir
   s<<cmd;
   s<<m_path;
   KIO::SimpleJob *umountJob=KIO::special(dummyUrl, data, false);
   connect( umountJob, SIGNAL( result( KIO::Job * ) ), SLOT( umountResult( KIO::Job * ) ) );
   m_smbumountAction->setEnabled(false);
   m_smbmountAction->setEnabled(false);
}

void SmbmounterPlugin::mountResult(KIO::Job *job)
{
   if (job && job->error())
      KMessageBox::information(0,i18n("<qt>Mounting of share <b>%1</b> from host <b>%2</b> failed.</qt>").arg(m_share).arg(m_host));
   else
      KMessageBox::information(0,i18n("<qt>The share <b>%1</b> from host <b>%2</b> has been mounted under <b>%3</b>.</qt>").arg(m_share).arg(m_host).arg(m_path));
   updateActions();
}

void SmbmounterPlugin::umountResult(KIO::Job *job)
{
   if (job && job->error())
      KMessageBox::information(0,i18n("<qt>Umounting of share <b>%1</b> from host <b>%2</b> failed.</qt>").arg(m_share).arg(m_host));
   else
      KMessageBox::information(0,i18n("<qt>The share <b>%1</b> from host <b>%2</b> has been umounted from <b>%3</b></qt>.").arg(m_share).arg(m_host).arg(m_path));
   updateActions();
}


//hard coded mount path, could be made configurable, but what for ?
QString SmbmounterPlugin::buildMountPath(const QString& host, const QString& share)
{
   QString path=QDir::homeDirPath();
   path+="/smb_network/"+host.lower()+"/"+share.lower();
   return path;
}

void SmbmounterPlugin::getHostAndShare(const KURL& url, QString& host, QString& share)
{
   QString path=url.path();
   host=url.host();
   share="";
   bool hostIsEmpty=host.isEmpty();

   int i=0;
   QStringList list=QStringList::split("/",path);
   for (QStringList::Iterator it=list.begin(); it!=list.end(); it++)
   {
      if (hostIsEmpty)  //smb:/wg/host/ - type url
      {
         if (i==1)   //the host
         {
            host=(*it);
         }
         else if (i==2)
         {
            share=(*it);
            break;
         }
      }
      else
      {
         if (i==0)
         {
            share=(*it);
            break;
         }
      }
      i++;
   }
}

bool SmbmounterPlugin::isMounted(const QString& path)
{
   //quick and dirty
   QFile mtab("/etc/mtab");
   if (!mtab.open(IO_ReadOnly))
      return false;
   QString mtabContents=QString::fromLocal8Bit(mtab.readAll());
   return (mtabContents.contains(path));
}

K_EXPORT_COMPONENT_FACTORY( konq_smbmounterplugin, KGenericFactory<SmbmounterPlugin> )

#include "smbmounterplugin.moc"

