/***************************************************************************
 *   Copyright (C) 2004-2010 by Giovanni Venturi                           *
 *   giovanni@ksniffer.org                                                 *
 *                                                                         *
 *   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 Steet, Fifth Floor, Boston, MA  02110-1301, USA.          *
 ***************************************************************************/

#include <QString>
#include <QPushButton>

#include <KProcess>
#include <KLocale>
#include <KStandardDirs>
#include <KSocketAddress>

#include <KDebug>

#include "KInfoIP.h"
#include "DisplayData.h"

KInfoIP::KInfoIP()
{
  // assign initial values
  m_IP = "";
  m_buttonCancel = true;

  // assign applications fullpathname
  m_whoisExec = KStandardDirs::findExe("whois");
  m_tracerouteExec = KStandardDirs::findExe("traceroute");
  m_pingExec = KStandardDirs::findExe("ping");
  m_digExec = KStandardDirs::findExe("dig");
  m_hostExec = KStandardDirs::findExe("host");
  m_nslookupExec = KStandardDirs::findExe("nslookup");

  // assign the KPopupMenu refer
  m_popupMenu = new KPopupMenu();
}

KInfoIP::~KInfoIP()
{
  delete m_displayDataBox;
  delete m_popupMenu;
}


KPopupMenu *KInfoIP::createPopupMenu()
{
  m_popupMenu->insertTitle("info from...", 0);

  // add the menu items if their executable exists
  if (m_whoisExec != QString::null)
    m_popupMenu->insertItem("whois", WHOIS_CMD);
  if (m_tracerouteExec != QString::null)
    m_popupMenu->insertItem("traceroute", TRACEROUTE_CMD);
  if (m_pingExec != QString::null)
    m_popupMenu->insertItem("ping", PING_CMD);
  if (m_digExec != QString::null)
    m_popupMenu->insertItem("dig", DIG_CMD);
  if (m_hostExec != QString::null)
    m_popupMenu->insertItem("host", HOST_CMD);
  if (m_nslookupExec != QString::null)
    m_popupMenu->insertItem("nslookup", NSLOOKUP_CMD);

  // link the menu items to the action
  connect(m_popupMenu, SIGNAL(activated(int)), this, SLOT(showData(int)));

  return m_popupMenu;
}


bool KInfoIP::manageIP( const QString& ip )
{
  KNetwork::KIpAddress kip(ip);

  if (kip.version() != 0) // it's 4 or 6 according to the IP version (if it's a regular IP address)
  {
    m_IP = ip;
    m_popupMenu->changeTitle(0, i18nc("popup menu header", "Info from %1", ip));

    return true;
  }
  else
    return false;
}


void KInfoIP::showData( int id )
{
  QString caption;
  m_cmd = new KProcess;
  m_idApplication = id;

  switch(id)
  {
    case WHOIS_CMD:
      *m_cmd << m_whoisExec;
      caption = "whois %1";
      break;
    case TRACEROUTE_CMD:
      *m_cmd << m_tracerouteExec;
      caption = "traceroute %1";
      break;
    case PING_CMD:
      *m_cmd << m_pingExec;
      caption = "ping %1";
      break;
    case DIG_CMD:
      *m_cmd << m_digExec;
      caption = "dig %1";
      break;
    case HOST_CMD:
      *m_cmd << m_hostExec;
      caption = "host %1";
      break;
    case NSLOOKUP_CMD:
      *m_cmd << m_nslookupExec;
      caption = "nslookup %1";
      break;
    default:
      kdDebug() << "operation not supported";
      return;
  }
  *m_cmd << m_IP;

  connect(m_cmd, SIGNAL( receivedStdout( KProcess*, char*, int ) ), this, SLOT( gotMessage( KProcess*, char*, int ) ));
  connect(m_cmd, SIGNAL( receivedStderr( KProcess*, char*, int ) ), this, SLOT( gotMessage( KProcess*, char*, int ) ));
  connect(m_cmd, SIGNAL( processExited( KProcess* ) ), this, SLOT( commandExited() ));

  m_displayDataBox = new DisplayData();
  m_displayDataBox->setCaption( caption.arg(m_IP) );
  m_stdoutString = "";

  connect(m_displayDataBox->m_buttonCancelOk, SIGNAL(clicked()), this, SLOT(okCancelClicked()));

  m_cmd->start( KProcess::NotifyOnExit, KProcess::AllOutput );
  m_displayDataBox->exec();
  delete m_displayDataBox;
}


void KInfoIP::gotMessage( KProcess *proc, char *buffer, int buflen )
{
  QString myBuf = QString::fromLatin1( buffer, buflen );

  Q_UNUSED( proc );
  m_stdoutString.append( myBuf );
  m_displayDataBox->setText( m_stdoutString );
}


void KInfoIP::okCancelClicked()
{
  if (m_buttonCancel)
  {
    // KProcess application has to be stopped
    m_buttonCancel = false;
    disconnect(m_cmd, SIGNAL( receivedStdout( KProcess*, char*, int ) ), this, SLOT( gotMessage( KProcess*, char*, int ) ));
    disconnect(m_cmd, SIGNAL( receivedStderr( KProcess*, char*, int ) ), this, SLOT( gotMessage( KProcess*, char*, int ) ));
    m_cmd->kill();
    m_displayDataBox->showSave();
  }
  else
  {
    // clicked the "Ok" button
    m_displayDataBox->gotData();
    delete m_cmd;
    m_buttonCancel = true;
  }
}


void KInfoIP::commandExited()
{
  m_buttonCancel = false;
  m_displayDataBox->showSave();
  if (!m_stdoutString.isEmpty())
    m_displayDataBox->setText( m_stdoutString );
  else
    if (m_idApplication == 1)
      m_displayDataBox->setText( i18n("Cannot access the WHOIS databases.\nMaybe no internet connection available?") );
    else
      m_displayDataBox->setText( i18n("Are you sure your internet connection is available?") );
}

#include "KInfoIP.moc"
