/***************************************************************************
 *   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 <QtCore/QList>
#include <QtNetwork/QNetworkInterface>
#include <QtNetwork/QNetworkAddressEntry>

#include <KLocale>

//solid specific includes
/*#include <solid/deviceinterface.h>
#include <solid/networking.h>
#include <solid/device.h>
#include <solid/networkinterface.h>
*/

#include "NetworkDeviceList.h"

NetworkDeviceList::NetworkDeviceList()
{
  m_index = -1;
  detect();
}


NetworkDeviceList::~NetworkDeviceList()
{
  m_netDeviceList.clear();
}


void NetworkDeviceList::detect()
{
  int i;
  QString status;

  //m_netDeviceList->setAutoDelete(true);
  m_netDeviceList.clear();

//  QList<Solid::Device> netlist = Solid::Device::listFromType(Solid::DeviceInterface::NetworkInterface, QString());

  //check to see if no network devices were found
/*  if(netlist.empty())
  {
    kDebug() << "No network devices found!";
    return;
  }

  int i, j;

  for ( i = 0; i < netlist.count(); i++  )
  {
    Solid::Device device = netlist[i];
    Solid::NetworkInterface *netdev = device.as<Solid::NetworkInterface>();
    //keep the program from crashing in the event that there's a bug in solid
    if(!netdev)
    {
      kDebug() << "Device could not be converted.  There is a bug.";
      return;
    }
    if (netdev->ifaceName() != "lo")
    {
      if (netdev->macAddress() != 0)
        kDebug() << netdev->ifaceName() << " has MAC: " << netdev->hwAddress();
    }
    else
      kDebug() << "Address: any";
  }
  */

  QList<QNetworkInterface> nis = QNetworkInterface::allInterfaces();
  for ( i = 0; i < nis.count(); i++ )
  {
    QList<QNetworkAddressEntry> list = nis[i].addressEntries();
    if ( list.count() > 0)
    {
      if ((nis[i].flags() & QNetworkInterface::IsUp) == QNetworkInterface::IsUp)
        status = i18nc("State of network card is connected", "Up");
      else
        status = i18nc("State of network card is disconnected", "Down");
      NetworkDevice netDevice(nis[i].name(), list.at(0).ip().toString(), list.at(0).netmask().toString(),
        status, nis[i].hardwareAddress());
#warning status it is unuseful... better remove it?
      if ((nis[i].flags() & QNetworkInterface::IsUp) == QNetworkInterface::IsUp) m_netDeviceList << netDevice;
    }
  }
}


/*QString NetworkDevice::HWaddr2String( char *hwaddr )
{
  QString ret;
  int i;

  for (i=0; i<6; i++, hwaddr++) {
    int v = (*hwaddr & 0xff);
    QString num = QString("%1").arg(v,0,16).upper();
    if (num.length() < 2)
      num.prepend("0");
    if (i>0)
      ret.append(":");
    ret.append(num);
  }
  return ret;
}*/


NetworkDevice NetworkDeviceList::device( const QString& devName )
{
  #warning but NetworkDevice ret is destroyed when exit method?
  NetworkDevice ret;

  m_index = 0;
  if (m_netDeviceList.count() > 0)
  {
    while ( (m_index < m_netDeviceList.count()) && (m_netDeviceList.at(m_index).name() != devName) )
      m_index++;

    // if execeed the index no found network device into the list
    if (m_index == m_netDeviceList.count())
      m_index = -1;
    else
      ret = m_netDeviceList.at(m_index);
  }

  return ret;
}


// getting functions
QString NetworkDeviceList::name() const
{
  QString ret;

  if (m_index >= 0)
    ret = m_netDeviceList.at(m_index).name();

  return ret;
}


QString NetworkDeviceList::ipAddress() const
{
  QString ret;

  if (m_index >= 0)
    ret = m_netDeviceList.at(m_index).ipAddress();

  return ret;
}


QString NetworkDeviceList::netmask() const
{
  QString ret;

  if (m_index >= 0)
    ret = m_netDeviceList.at(m_index).netmask();

  return ret;
}


QString NetworkDeviceList::state() const
{
  QString ret;

  if (m_index >= 0)
    ret = m_netDeviceList.at(m_index).state();

  return ret;
}


QString NetworkDeviceList::hwAddress() const
{
  QString ret;

  if (m_index >= 0)
    ret = m_netDeviceList.at(m_index).hwAddress();

  return ret;
}


// the following function returns a StringList for the ComboBox
QStringList NetworkDeviceList::interfaceList() const
{
  QStringList list;
  int i;

  for (i = 0; i < m_netDeviceList.count(); i++)
    list << m_netDeviceList.at(i).name();
  list.sort();
  list << "any";
  
  return list;
}
