/*
 * Copyright (C) 2004 Robert Hogan <robert at roberthogan dot net>
 */
#include <config.h>


#include "kuarantine.h"
#include "dbviewer.h"
#include "klamav.h"


#include <tdelocale.h>
#include <kiconloader.h>
#include <tdemenubar.h>
#include <kstatusbar.h>
#include <kkeydialog.h>
#include <tdeio/netaccess.h>
#include <tdefiledialog.h>



#include <kbuttonbox.h>
#include <kurlrequester.h>
#include <kurlcompletion.h>
#include <kcombobox.h>
#include <tqlayout.h>
#include <tdemessagebox.h>
#include <kstandarddirs.h>


Kuarantine::Kuarantine(TQWidget *parent, const char *name)
    : TQWidget(parent, name)
{

    config = TDEGlobal::config();
    config->setGroup("Kuarantine");
    lastQuarLocations = config->readListEntry("KuarantineLocations");

    //kdDebug() << "in quarantine " << endl;    
    if (lastQuarLocations.isEmpty()){
        createQuarDir();
     }else{
        for (TQStringList::Iterator it = lastQuarLocations.begin(); it == lastQuarLocations.begin(); it++ )
        quarloc = *it;
        if (!(TDEIO::NetAccess::exists(quarloc,true,NULL))){
            KMessageBox::information (this,i18n( "Your current quarantine location ('%1') no longer exists. I'm going to attempt to create a new one.").arg(quarloc));
            createQuarDir();
        }
    }
        

        
    //Get Items for this location

    lastQuarItems = config->readListEntry(TQString("Items %1").arg(quarloc));

    if (lastQuarItems.isEmpty()){
        config->writeEntry(TQString("Items %1").arg(quarloc), "");
        lastQuarItems = config->readListEntry(TQString("Items %1").arg(quarloc));
    }
    
    //Get History for this location

    lastHistoryItems = config->readListEntry(TQString("History %1").arg(quarloc));

    if (lastHistoryItems.isEmpty()){
        config->writeEntry(TQString("History %1").arg(quarloc), "");
        config->sync();
        lastHistoryItems = config->readListEntry(TQString("History %1").arg(quarloc));
    }
    
    //Create GUI    

    TQVBoxLayout *vbox = new TQVBoxLayout(this, KDialog::marginHint(),
            KDialog::spacingHint(), "vbox");

    TQGroupBox *group = new TQGroupBox(i18n("Quarantine Location"), this);
    vbox->addWidget(group);

    TQGridLayout *layout = new TQGridLayout( group, 9, 3, KDialog::spacingHint(),
            KDialog::spacingHint(), "layout");
    layout->addRowSpacing(0, group->fontMetrics().height());
    layout->setColStretch(0, 1);
    layout->setColStretch(1, 1);

    TQWidget *hlp = new TQWidget( group );
    layout->addMultiCellWidget(hlp, 1,1, 0,2);
    TQHBoxLayout *dir_layout = new TQHBoxLayout(hlp, KDialog::spacingHint() );

    TQLabel *dir_label = new TQLabel(i18n("&Directory:"), hlp);
    dir_label->setFixedSize(dir_label->sizeHint());
        dir_label->adjustSize();
    dir_layout->addWidget(dir_label);


    // anders: KDE is an amazing tool:)
    dir_combo = new KURLRequester( new KComboBox(true, hlp), hlp, "dir combo" );
    dir_combo->completionObject()->setMode(KURLCompletion::DirCompletion);

    dir_combo->comboBox()->insertStringList(lastQuarLocations);
    dir_combo->setMode( KFile::Directory|KFile::LocalOnly );
    dir_layout->addWidget(dir_combo);
    dir_label->setBuddy(dir_combo);
    
    connect( dir_combo, TQ_SIGNAL(urlSelected(const TQString &)),
        TQ_SLOT(updateLastQuarLocations()) );
    connect( dir_combo, TQ_SIGNAL(textChanged(const TQString &)),
        TQ_SLOT(updateLastQuarLocations()) );



    TQGroupBox *group2 = new TQGroupBox(i18n("Contents Of Quarantine"), this);
    vbox->addWidget(group2);

    TQGridLayout *layout2 = new TQGridLayout( group2, 9, 3, KDialog::spacingHint(),
            KDialog::spacingHint(), "layout2");
    layout2->addRowSpacing(0, group2->fontMetrics().height());
    layout2->setColStretch(0, 1);
    layout2->setColStretch(1, 1);

    TQWidget *hlp2 = new TQWidget( group2 );
    layout2->addMultiCellWidget(hlp2, 1,1, 0,2);
    TQHBoxLayout *dir_layout2 = new TQHBoxLayout(hlp2, KDialog::spacingHint() );


//     currentbox = new TQListBox(hlp2);
//     TQFontMetrics rb_fm(currentbox->fontMetrics());
//     currentbox->setMinimumSize(rb_fm.width("0")*25,
//                 rb_fm.lineSpacing()*8);
//     dir_layout2->addWidget(currentbox);

    currentbox = new TQListView(hlp2);
        currentbox->setShowSortIndicator(true);
    
    TQFontMetrics rb_fm(currentbox->fontMetrics());
    //currentbox->setMinimumSize(rb_fm.width("0")*55,
    //            rb_fm.lineSpacing()*15);
    //kdDebug() << ((currentbox->width())/3) << endl;
    currentbox->addColumn( i18n( "Name of File" ),0);
        currentbox->addColumn( i18n( "Name of Virus Found" ),0);
    currentbox->addColumn( i18n( "Date Quarantined" ),0);
    currentbox->setResizeMode(TQListView::AllColumns);
    currentbox->setSelectionMode( TQListView::Extended );
    currentbox->setAllColumnsShowFocus(true);

    qmenu = new TQPopupMenu( currentbox );

        connect(currentbox, TQ_SIGNAL( contextMenuRequested( TQListViewItem *, const TQPoint& , int ) ), 
        this, TQ_SLOT( slotRMB( TQListViewItem *, const TQPoint &, int ) ) );

    dir_layout2->addWidget(currentbox);
    
    //layout->addMultiCellWidget(currentbox);

    refresh();

    KButtonBox *actionbox = new KButtonBox(hlp2, TQt::Vertical);
    actionbox->addStretch();
    refresh_button = actionbox->addButton(i18n("&Refresh"));
    refresh_button->setDefault(true);
    search_button = actionbox->addButton(i18n("&Restore"));
    search_button->setDefault(true);
    cancel_button = actionbox->addButton(i18n("&Delete"));
    actionbox->addStretch();
        actionbox->adjustSize();
    actionbox->layout();

    dir_layout2->addWidget(actionbox);


    connect( refresh_button, TQ_SIGNAL(clicked()),
        TQ_SLOT(refresh()) );

    connect( search_button, TQ_SIGNAL(clicked()),
        TQ_SLOT(slotSearch()) );
    connect( cancel_button, TQ_SIGNAL(clicked()),
        TQ_SLOT(slotCancel()) );



    TQGroupBox *group3 = new TQGroupBox(i18n("Quarantine History"), this);
    vbox->addWidget(group3);

    TQGridLayout *layout3 = new TQGridLayout( group3, 9, 2, KDialog::spacingHint(),
            KDialog::spacingHint(), "layout3");
    layout3->addRowSpacing(0, group3->fontMetrics().height());
    layout3->setColStretch(0, 1);
    layout3->setColStretch(1, 1);

    TQWidget *hlp3 = new TQWidget( group3 );
    layout3->addMultiCellWidget(hlp3, 1,1, 0,2);
    TQHBoxLayout *dir_layout3 = new TQHBoxLayout(hlp3, KDialog::spacingHint() );


//     historybox = new TQListBox(hlp3);
//     TQFontMetrics rb_fm3(historybox->fontMetrics());
//     historybox->setMinimumSize(rb_fm3.width("0")*25,
//                 rb_fm3.lineSpacing()*8);
//     dir_layout3->addWidget(historybox);

    historybox = new TQListView(hlp3);
        historybox->setShowSortIndicator(true);

    TQFontMetrics rb_fm2(historybox->fontMetrics());
    //historybox->setMinimumSize(rb_fm2.width("0")*55,
    //            rb_fm2.lineSpacing()*15);
    historybox->addColumn( i18n( "Name of File" ),(historybox->width()));
        historybox->addColumn( i18n( "Name of Virus Found" ),(historybox->width()));
    historybox->addColumn( i18n( "Date Quarantined" ),(historybox->width()));
    historybox->setResizeMode(TQListView::AllColumns);
    historybox->setSelectionMode( TQListView::Extended );
    historybox->setAllColumnsShowFocus(true);

    hmenu = new TQPopupMenu( historybox );

        connect(historybox, TQ_SIGNAL( contextMenuRequested( TQListViewItem *, const TQPoint& , int ) ), 
        this, TQ_SLOT( slotRMB( TQListViewItem *, const TQPoint &, int ) ) );

    dir_layout3->addWidget(historybox);
    //layout->addMultiCellWidget(historybox, 2, 2, 0, 2);

    KButtonBox *actionbox3 = new KButtonBox(hlp3, TQt::Vertical);
    actionbox3->addStretch();
    search_button3 = actionbox3->addButton(i18n("&Clear All"));
    search_button3->setDefault(true);
    cancel_button3 = actionbox3->addButton(i18n("&Delete"));
    cancel_button3->setEnabled(true);
    actionbox3->addStretch();
    actionbox3->layout();

    dir_layout3->addWidget(actionbox3);

    refreshhistory();

    connect( search_button3, TQ_SIGNAL(clicked()),
        TQ_SLOT(slotClearHistory()) );
    connect( cancel_button3, TQ_SIGNAL(clicked()),
        TQ_SLOT(slotDeleteHistory()) );

    
    
}

Kuarantine::~Kuarantine()
{
}

void Kuarantine::refresh()
{


    TQStringList obsoleteQuarItems;
    config = TDEGlobal::config();
    config->setGroup("Kuarantine");
    lastQuarItems = config->readListEntry(TQString("Items %1").arg(quarloc));
    
    if (!(TDEIO::NetAccess::exists(quarloc,true,NULL))){
        KMessageBox::information (this,i18n("Your current quarantine location ('%1') no longer exists. I'm going to attempt to create a new one.").arg(quarloc));
        createQuarDir();
    }else{

        currentbox->clear();
        for (TQStringList::Iterator it = lastQuarItems.begin(); it != lastQuarItems.end(); it++ ){
                
                TQString fname = getFileName(*it);    
                TQString itemname = getVirusName(*it);
                TQString when = getWhen(*it);
                
                TQStringList tokens = TQStringList::split ( "/", fname, false );
                TQString qname = tokens.last();
                
                qname.prepend("/");
                qname.prepend(quarloc);
                qname.append(":"+when);
                //kdDebug() << qname << endl;
                if (TDEIO::NetAccess::exists(qname,true,NULL)){
                    //currentbox->insertItem(*it);
                    new TQListViewItem( currentbox, fname, itemname,when);
                }else{
                    //kdDebug() << qname << "doesna exist" << endl;
                    obsoleteQuarItems.append(*it);
                }
        }
    
        for (TQStringList::Iterator it = obsoleteQuarItems.begin(); it != obsoleteQuarItems.end(); it++ )
            lastQuarItems.remove(*it);
        
        config->writeEntry(TQString("Items %1").arg(quarloc), lastQuarItems);
    }
    config->sync();

}

void Kuarantine::refreshhistory()
{
    config = TDEGlobal::config();
    config->setGroup("Kuarantine");
    lastHistoryItems = config->readListEntry(TQString("History %1").arg(quarloc));

    historybox->clear();
    for (TQStringList::Iterator it = lastHistoryItems.begin(); it != lastHistoryItems.end(); it++ ){
            TQString fname = getFileName(*it);    
            TQString itemname = getVirusName(*it);
            TQString when = getWhen(*it);

            new TQListViewItem( historybox, fname, itemname,when);
    }
}

void Kuarantine::load()
{
    TQString target;
    // the below code is what you should normally do.  in this
    // example case, we want the url to our own.  you probably
    // want to use this code instead for your app

        currentbox->clear();
    for (TQStringList::Iterator it = lastQuarItems.begin(); it != lastQuarItems.end(); it++ ){
            TQString fname = getFileName(*it);    
            TQString itemname = getVirusName(*it);
            TQString when = getWhen(*it);

            new TQListViewItem( currentbox, fname, itemname,when);
    }
}



void Kuarantine::slotSearch()
{
    //if (!(currentbox->selectedItem()))
    //    return;

    TQPtrList<TQListViewItem> list;

    TQListViewItemIterator it( currentbox, TQListViewItemIterator::Selected );
    
        while ( it.current() ) {

        TQListViewItem* tItem = it.current();
        config = TDEGlobal::config();
        config->setGroup("Kuarantine");
        lastQuarItems = config->readListEntry(TQString("Items %1").arg(quarloc));
        lastHistoryItems = config->readListEntry(TQString("History %1").arg(quarloc));
    
        TQString fname = tItem->text(0);
    
        TQStringList tokens = TQStringList::split ( "/", fname, false );
        TQString qname = tokens.last();
        qname.prepend("/");
        qname.prepend(quarloc);
        qname.append(":"+tItem->text(2));
        
        if (TDEIO::NetAccess::file_move(qname,fname)){
            lastQuarItems.remove(tItem->text(0)+":"+tItem->text(1)+":"+tItem->text(2));
            
            //currentbox->takeItem(currentbox->currentItem());
            list.prepend( it.current() );
            
            config->writeEntry(TQString("Items %1").arg(quarloc), lastQuarItems);
            config->sync();
        }else{
            KMessageBox::information (this,i18n("<p>There was a problem restoring <b>%1</b>. Check your diskspace, the permissions on the location you are restoring to, and whether a file with the same name already exists in that location. </p>").arg(fname));
        }
            ++it;
    }

for( TQListViewItem *item = list.first(); item; item = list.next() )
{
    delete item;
}


}


void Kuarantine::updateLastQuarLocations()
{


    config = TDEGlobal::config();
    config->setGroup("Kuarantine");
    lastQuarLocations = config->readListEntry("KuarantineLocations");
    
    if (lastQuarLocations.contains(dir_combo->url()) == 0) {
        dir_combo->comboBox()->insertItem(dir_combo->url(), 0);
        lastQuarLocations.prepend(dir_combo->url());
        if (lastQuarLocations.count() > 10) {
            lastQuarLocations.remove(lastQuarLocations.fromLast());
            dir_combo->comboBox()->removeItem(dir_combo->comboBox()->count() - 1);
        }
    }else{
        
        lastQuarLocations.remove(dir_combo->url());
        lastQuarLocations.prepend(dir_combo->url());
    }
    config->writeEntry("KuarantineLocations", lastQuarLocations);
    config->sync();
    quarloc = dir_combo->url();
    
    refresh();
    refreshhistory();
}


void Kuarantine::slotCancel()
{

    //if (!(currentbox->selectedItem()))
    //    return;
    TQPtrList<TQListViewItem> list;

    TQListViewItemIterator it( currentbox, TQListViewItemIterator::Selected );
    
        while ( it.current() ) {
            
        //TQListViewItem* tItem = ( *it );
        //if (tItem->isSelected()){
            config = TDEGlobal::config();
            config->setGroup("Kuarantine");
            lastQuarItems = config->readListEntry(TQString("Items %1").arg(quarloc));
            lastHistoryItems = config->readListEntry(TQString("History %1").arg(quarloc));
            
            TQString QuarLocation = dir_combo->url();
        
        
        
            //TQStringList tokens = TQStringList::split ( ":", ( it.current() )->text(), false );
            TQString fname = ( it.current() )->text(0);
            TQString itemname = ( it.current() )->text(1);
            TQString when = ( it.current() )->text(2);
            
            TQStringList tokens = TQStringList::split ( "/", fname, false );
            TQString qname = tokens.last();
            qname.prepend("/");
            qname.prepend(QuarLocation);
            qname.append(":"+( it.current() )->text(2));
            
            if (TDEIO::NetAccess::del(qname,NULL)){
        
                lastQuarItems.remove(( it.current() )->text(0)+":"+( it.current() )->text(1)+":"+( it.current() )->text(2));
                lastHistoryItems.prepend(( it.current() )->text(0)+":"+( it.current() )->text(1)+":"+( it.current() )->text(2));
        
                new TQListViewItem( historybox, fname, itemname,when);
            
                //historybox->inser( it.current() )(( it.current() )->text());
                //currentbox->takeItem(( it.current() ));
                list.prepend( it.current() );
            }else{
                KMessageBox::information (this,i18n( "There was a problem deleting the file. Is there a problem with the permissions on the quarantine folder? " ));
            }
        //}
            ++it;
    }

    for( TQListViewItem *item = list.first(); item; item = list.next() )
    {
        delete item;
    }
    
    config->writeEntry(TQString("Items %1").arg(quarloc), lastQuarItems);
    config->writeEntry(TQString("History %1").arg(quarloc), lastHistoryItems);
    config->sync();

    
}





void Kuarantine::slotClearHistory()
{

    historybox->clear();
    config = TDEGlobal::config();
    config->setGroup("Kuarantine");
    lastHistoryItems = config->readListEntry(TQString("History %1").arg(quarloc));

    if (lastHistoryItems.isEmpty())
        return;

    lastHistoryItems.clear();

     config->writeEntry(TQString("History %1").arg(quarloc), lastHistoryItems);
     config->sync();



}

void Kuarantine::slotDeleteHistory()
{

    //if (!(historybox->selectedItem()))
    //    return;

    //TQListViewItem* tItem = historybox->selectedItem();

    config->setGroup("Kuarantine");
    lastHistoryItems = config->readListEntry(TQString("History %1").arg(quarloc));

           TQPtrList<TQListViewItem> list;

    TQListViewItemIterator it( historybox, TQListViewItemIterator::Selected );
    
        while ( it.current() ) {

        lastHistoryItems.remove(( it.current() )->text(0)+":"+( it.current() )->text(1)+":"+( it.current() )->text(2));
        //historybox->takeItem(historybox->curren( it.current() )());
        list.prepend( it.current() );
        ++it;
    }
    
    for( TQListViewItem *item = list.first(); item; item = list.next() )
    {
        delete item;

    }
    config->writeEntry(TQString("History %1").arg(quarloc), lastHistoryItems);
    config->sync();

}


void  Kuarantine::setDirName(TQString dir){
//    dir_combo->setEditText(dir);
    dir_combo->setURL(dir);
}

void  Kuarantine::createQuarDir(){

    TQString path = getenv("HOME");
    bool ok = true;
    // directory exist?
    path += "/.klamav";
    TQDir klamavdir(path);
    if (!klamavdir.exists() && !klamavdir.mkdir(path))
        ok = false;

    path += "/quarantine";
    if (ok)
    {
        TQDir klamavqdir(path);
        if (!klamavqdir.exists() && !klamavqdir.mkdir(path))
            ok = false;
        else
            chmod(path.ascii(),0700);
    }

    if (ok){
        quarloc = TQString("%1").arg(path);
        lastQuarLocations.append( TQString("%1").arg(path));
        config = TDEGlobal::config();
        config->setGroup("Kuarantine");
        config->writeEntry("KuarantineLocations", lastQuarLocations);
        config->sync();
        lastQuarLocations = config->readListEntry("KuarantineLocations");
        
    }
    
    KMessageBox::information (this,TQString(ok ? i18n( "Your default quarantine location has been set up as '%1'. You can change this to something else if you want to." ) : i18n( "I cannot create the directory '%1' for you. Something is wrong with your HOME or klamav directory. You have to adjust your quarantine directory by your self." )).arg(path));
    
}

TQString Kuarantine::getFileName(TQString entry){

    int fnameStartPoint = 0;
    int dtStartPoint = entry.findRev(":");
    int fnameEndPoint = entry.findRev(":", (signed int)-((entry.length() - dtStartPoint)+1));
    TQString fname = entry.mid(fnameStartPoint,(fnameEndPoint - fnameStartPoint));
    
    //kdDebug() << fname << endl;
    
    return fname;    
    
}

TQString Kuarantine::getVirusName(TQString entry){

    int dtStartPoint = entry.findRev(":");
    int fnameEndPoint = entry.findRev(":", (signed int)-((entry.length() - dtStartPoint)+1));
    
    TQString itemName = entry.mid((fnameEndPoint+1),((dtStartPoint+1) - (fnameEndPoint+2)));
    
    //kdDebug() << itemName << endl;
    
    return itemName.stripWhiteSpace();    
    
}

TQString Kuarantine::getWhen(TQString entry){

    int dtStartPoint = entry.findRev(":");
    
    TQString when = entry.mid((dtStartPoint+1),(entry.length() - (dtStartPoint+1)));
    
    //kdDebug() << when << endl;
    
    return when;    
    
}

void Kuarantine::slotRMB( TQListViewItem* Item, const TQPoint & point, int )
{
    if( Item ){
    
    TQPixmap gicon;
    TQPixmap vicon;
    TQPixmap ticon;
        TQPixmap vlicon;

        TQString iconPath = locate("cache", KMimeType::favIconForURL("http://www.viruspool.net")+".png");
        if ( iconPath.isEmpty() )
          vicon = SmallIcon("edit-find");
        else
          vicon = TQPixmap( iconPath );

        iconPath = locate("cache", KMimeType::favIconForURL("http://www.google.com")+".png");
        if ( iconPath.isEmpty() )
          gicon = SmallIcon("edit-find");
        else
          gicon = TQPixmap( iconPath );

        iconPath = locate("cache", KMimeType::favIconForURL("http://www.trendmicro.com")+".png");
        if ( iconPath.isEmpty() )
          ticon = SmallIcon("edit-find");
        else
          ticon = TQPixmap( iconPath );

        iconPath = locate("cache", KMimeType::favIconForURL("http://www.viruslist.com")+".png");
        if ( iconPath.isEmpty() )
          vlicon = SmallIcon("edit-find");
        else
          vlicon = TQPixmap( iconPath );


    if (Item->listView() == currentbox){
        qmenu->clear();
        qmenu->insertItem( ticon,i18n("Search for %1 with Trend Micro").arg(Item->text(1)), this, TQ_SLOT(slotTrendMicroCurrent()) );
        qmenu->insertItem( gicon,i18n("Search for %1 with Google").arg(Item->text(1)), this, TQ_SLOT(slotGoogleCurrent()) );
    
        qmenu->popup( point );
    }else if (Item->listView() == historybox){
        hmenu->clear();
        hmenu->insertItem( ticon,i18n("Search for %1 with Trend Micro").arg(Item->text(1)), this, TQ_SLOT(slotTrendMicroHistory()) );
        hmenu->insertItem( gicon,i18n("Search for %1 with Google").arg(Item->text(1)), this, TQ_SLOT(slotGoogleHistory()) );
    
        hmenu->popup( point );
    }
    }
}

void Kuarantine::slotGoogleCurrent()
{
    TQString name = currentbox->currentItem()->text(1);
    tdemain->klamdb->slotExternal(name,"Google");
}

void Kuarantine::slotTrendMicroCurrent()
{
    TQString name = currentbox->currentItem()->text(1);
    tdemain->klamdb->slotExternal(name, "TrendMicro");
}

void Kuarantine::slotGoogleHistory()
{
    TQString name = historybox->currentItem()->text(1);
    tdemain->klamdb->slotExternal(name,"Google");
}

void Kuarantine::slotTrendMicroHistory()
{
    TQString name = historybox->currentItem()->text(1);
    tdemain->klamdb->slotExternal(name, "TrendMicro");
}

#include "kuarantine.moc"
