/***************************************************************************
                          kmesstest.cpp  -  description
                             -------------------
    begin                : Sun Jan 5 2003
    copyright            : (C) 2003 by Mike K. Bennett
    email                : mkb137b@hotmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "kmesstest.h"

#include "chat/chat.h"
#include "chat/chathistorymanager.h"
#include "chat/chathistorywriter.h"
#include "chat/chatmaster.h"
#include "chat/chatview.h"
#include "chat/chatwindow.h"
#include "chat/contactswidget.h"
#include "chat/xsltransformation.h"
#include "contact/contact.h"
#include "contact/contactbase.h"
#include "contact/contactextension.h"
#include "contact/group.h"
#include "contact/specialgroups.h"
#include "dialogs/addcontactdialog.h"
#include "dialogs/chathistorydialog.h"
#include "dialogs/contactaddeduserwidget.h"
#include "dialogs/contactaddeduserdialog.h"
#include "dialogs/transferentry.h"
#include "dialogs/transferwindow.h"
#include "model/contactlist.h"
#include "network/soap/httpsoapconnection.h"
#include "network/soap/msnappdirectoryservice.h"
#include "network/soap/soapmessage.h"
#include "network/msnchallengehandler.h"
#include "network/msnnotificationconnection.h"
#include "network/msnswitchboardconnection.h"
#include "notification/contactstatusnotification.h"
#include "notification/systemtraywidget.h"
#include "settings/accountsettingsdialog.h"
#include "utils/nowlisteningclient.h"
#include "utils/richtextparser.h"
#include "accountsmanager.h"
#include "kmessviewdelegate.h"
#include "currentaccount.h"
#include "emoticonmanager.h"
#include "kmess.h"
#include "kmessapplication.h"
#include "kmessview.h"
#include "../tests/old_richtextparser.h"

#include <QTime>
#include <QFile>
#include <QImage>

#include <KMessageBox>



// The constructor
KMessTest::KMessTest(KMess *kmess)
 : QObject(kmess)
 , quitAfterTest_(false)
 , kmess_(kmess)
{
  // Used to quit. Could also be useful to the tests
  kmessApp_ = static_cast<KMessApplication*>( kapp );

  setObjectName("KMessTest");
}



// The destructor
KMessTest::~KMessTest()
{
  kmDebug() << "DESTROYED";
}



#define  TESTCASE(name, action) testcases.append( name ); if( testName == name ) { action; return; }


/**
 * The main testing function.
 * Runs a given test based on a command line argument.
 */
void KMessTest::runTest( const QString &testName )
{
  // Add the tests, which can be run from debug builds using:
  // ./kmess --runtest <name>

  kmDebug() << "Running test:" << testName;
  kmDebug() << "----------------------------------------";
  kmDebug();

  QStringList testcases;

  TESTCASE( "transferwindow",      testTransferWindow() );
  TESTCASE( "chathistory",         testChatHistoryDialog() );
  TESTCASE( "chatwindow",          testChatWindow() );
  TESTCASE( "challenge",           testChallengeHandler() );
  TESTCASE( "crash",               testCrash() );
  TESTCASE( "addcontact",          testAddContactDialog() );
  TESTCASE( "contactaddeduser",    testContactAddedUserDialog() );
  TESTCASE( "msnplus",             testMsnPlus() );
  TESTCASE( "msnplusinteractive",  testMsnPlusInteractive() );
  TESTCASE( "parserbenchmark",     benchmarkParser() );
  TESTCASE( "ns",                  testNotificationConnection() );
  TESTCASE( "contactlist",         testContactList() );
  TESTCASE( "connect",             testConnect() );
  TESTCASE( "settings",            testSettings() );
  TESTCASE( "sb",                  testSwitchboardConnection() );
  TESTCASE( "notifications",       testNotifications() );
  TESTCASE( "nowlistening",        testNowListening() );
  TESTCASE( "soap",                testSoapConnection() );
  TESTCASE( "xslt",                testXslTransformation() );
  TESTCASE( "systemtray",          testSystemTray() );
  TESTCASE( "offlinemessages",     testOfflineMessages() );
  qSort( testcases );
  kmDebug() << "Test case not found, available cases:";
  kmDebug() << testcases.join( ", " );

  quitAfterTest_ = true;
}



// Cleans up and schedules quitting kmess if necessary
void KMessTest::endTest()
{
  kmDebug();
  kmDebug() << "----------------------------------------";

  if( quitAfterTest_ )
  {
    // We can't quit (and also clean up the memory) now, since
    // the event loop hasn't started yet. Delay it a bit.
    kmDebug() << "Test case ended, quitting KMess.";

    kmessApp_->setQuitSelected( true );
    QTimer::singleShot( 1000, kmess_, SLOT( menuQuit() ) );
  }
}



void KMessTest::testChatHistoryDialog()
{
  testGroupsAndContacts();
  CurrentAccount::instance()->setLoginInformation( "thorless@hotmail.com", "Testing Account", "test" );

//   ChatHistoryDialog *dialog = new ChatHistoryDialog( kmess_ );
//   dialog->setInitialContact( CurrentAccount::instance()->getHandle(), "test2@test.com" );
//   dialog->exec();

  ChatHistoryManager::setAccount( "thorless@hotmail.com" );

//   ChatHistoryWriter* writer = ChatHistoryManager::getWriter( "starforcer@hotmail.com" );
//   writer->

//   ChatHistoryManager::lastChatLog("contact@msn.com" );
//   kmDebug() << "Last chat history operation's result:" << ChatHistoryManager::result();

  quitAfterTest_ = true;
}



void KMessTest::testTransferWindow()
{
  int id;
  KIconLoader *loader = KIconLoader::global();
  TransferWindow *instance = TransferWindow::getInstance();

  id = instance->addEntry( "Filename1", 1234567890, true, QImage( loader->iconPath( "list-add", 48, false ) ) );
  kmDebug() << "Added ID: " << id;

  id = instance->addEntry( "Filename2", 34567890, false, QImage( loader->iconPath( "list-remove", 48, false ) ) );
  kmDebug() << "Added ID: " << id;

  id = instance->addEntry( "Filename3", 567890, true );
  kmDebug() << "Added ID: " << id;

//   TransferWindow::destroy();
}


void KMessTest::testChatWindow()
{
  testGroupsAndContacts();

  MimeMessage message( QString( "MIME-Version: 1.0\r\nContent-Type: text/plain;charset=UTF-8\r\nX-MMS-IM-Format: FN=Georgia; EF=; CO=c080ff; CS=0; PF=12\r\n\r\nTesting incoming chats! :D :D\r\n" ) );

  // Contact-started chat
  if( 1 )
  {
    MsnSwitchboardConnection *sb2 = new MsnSwitchboardConnection();
    sb2 = kmess_->chatMaster_->createSwitchboardConnection( sb2, "contact7@kmess.org" );
  //    kmess_->chatMaster_->switchboardConnections_.append( sb2 );
    ChatInformation chatInfo2( kmess_->msnNotificationConnection_, "contact7@kmess.org", "127.0.0.1", 1234, "5678.8765", "-1", ChatInformation::CONNECTION_CHAT );
    sb2->initialize( "contact7@kmess.org" );
    sb2->start( chatInfo2 );
    sb2->contactJoined( "contact7@kmess.org", "Contact 7", 0 );
//     Chat *chat = kmess_->chatMaster_->createChat( sb2 );
    sb2->parseChatMessage( "contact7@kmess.org", "Contact 7", "", message );
  }

    // User-started chat
  if( 1 )
  {
    MsnSwitchboardConnection *sb1 = new MsnSwitchboardConnection();
    kmess_->chatMaster_->switchboardConnections_.append( sb1 );
    ChatInformation chatInfo1( kmess_->msnNotificationConnection_, "contact1@kmess.org", -1, ChatInformation::CONNECTION_OFFLINE );
    sb1->initialize( "contact1@kmess.org" );
    sb1->start( chatInfo1 );

    kmess_->chatMaster_->createChat( sb1 );
//     sb1->parseChatMessage( "contact1@kmess.org", "Contact 1", "", message );
  }

  // Contact-started group chat
  if( 0 )
  {
    MsnSwitchboardConnection *sb3 = new MsnSwitchboardConnection();
    ChatInformation chatInfo3( kmess_->msnNotificationConnection_, "contact2@kmess.org", "127.0.0.1", 1234, "5678.8765", "-1", ChatInformation::CONNECTION_OFFLINE );
    sb3->initialize( "contact2@kmess.org" );
    sb3->start( chatInfo3 );
    kmess_->chatMaster_->switchboardConnections_.append( sb3 );
    sb3->contactJoined( "contact1@kmess.org", "Contact 1", 0 );
    sb3->contactJoined( "contact2@kmess.org", "Contact 2", 0 );
    sb3->contactJoined( "contact3@kmess.org", "Contact 3", 0 );
    sb3->contactJoined( "contact4@kmess.org", "Contact 4", 0 );
    sb3->contactJoined( "contact5@kmess.org", "Contact 5", 0 );
    sb3->contactJoined( "contact6@kmess.org", "Contact 6", 0 );
    sb3->contactJoined( "contact7@kmess.org", "Contact 7", 0 );
    sb3->contactJoined( "contact8@kmess.org", "Contact 8", 0 );
    sb3->contactJoined( "contact9@kmess.org", "Contact 9", 0 );
    sb3->contactJoined( "contact10@kmess.org", "Contact 10", 0 );

    kmess_->chatMaster_->createChat( sb3 );
    sb3->parseChatMessage( "contact2@kmess.org", "Contact 2", "", message );
    sb3->parseChatMessage( "contact5@kmess.org", "Contact 5", "", message );
  }

  // Wink
  if( 0 )
  {
    MsnSwitchboardConnection *sb4 = new MsnSwitchboardConnection();
    sb4 = kmess_->chatMaster_->createSwitchboardConnection( sb4, "contact7@kmess.org" );
  //    kmess_->chatMaster_->switchboardConnections_.append( sb4 );
    ChatInformation chatInfo4( kmess_->msnNotificationConnection_, "contact7@kmess.org", "127.0.0.1", 1234, "5678.8765", "-1", ChatInformation::CONNECTION_CHAT );
    sb4->initialize( "contact7@kmess.org" );
    sb4->start( chatInfo4 );
    sb4->contactJoined( "contact7@kmess.org", "Contact 7", 0 );
    Chat *chat = kmess_->chatMaster_->createChat( sb4 );

    // This is the wink "guitar smash"
    MimeMessage winkMessage( QString(
      "MIME-Version: 1.0\r\nContent-Type: text/x-msnmsgr-datacast\r\n\r\nID: 2\r\nData: <msnobj Creator=\""
      "contact7@kmess.org\" Size=\"35574\" Type=\"8\" Location=\"AzBXDxf+Tcdvcans2TCRnoXh_jg=\" Friendly="
      "\"dw==\" SHA1D=\"AzBXDxf+Tcdvcans2TCRnoXh/jg=\" SHA1C=\"5+JhvDZcpUpXNSkYttmciHP7a1U=\" stamp=\""
      "MIIInQYJKoZIhvcNAQcCoIIIjjCCCIoCAQExCzAJBgUrDgMCGgUAMCwGCSqGSIb3DQEHAaAfBB1BekJYRHhmK1RjZHZjYW5zMlR"
      "DUm5vWGgvamc9P6CCBrQwggawMIIFmKADAgECAgoFFrAoAAEAAAAJMA0GCSqGSIb3DQEBBQUAMHwxCzAJBgNVBAYTAlVTMRMwEQ"
      "YDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVB"
      "AMTHU1TTiBDb250ZW50IEF1dGhlbnRpY2F0aW9uIENBMB4XDTA1MDIyNTE4MDM0OFoXDTA1MDMxNTE4MTM0OFowUTESMBAGA1UE"
      "ChMJTWljcm9zb2Z0MQwwCgYDVQQLEwNNU04xLTArBgNVBAMTJDZhMjRkMTEwLWM2YmQtNDc2Ni1iMGNkLTU4YTBlMzc5NDlhNzC"
      "BnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0NIN35EKdW/q7ZaDI7IasI6m0T/ta19mxTBsyBA6C10NZ7TRM86QXw5WisYKBx"
      "S3jbupgo2D5hTHd4c7MStRM0efUgJDLTyzM7Kojem+FF16FYgEYaOeI2pSFZhP5I731B0k5jRwzMpQ6wlKg86diKv8PFUwOiOws"
      "41gfjCymvcCAwEAAaOCA+EwggPdMB0GA1UdDgQWBBTyHJ1dnGaT1pVQmP/YelVTNvYmMTAfBgNVHSUEGDAWBggrBgEFBQcDCAYK"
      "KwYBBAGCNzMBAzCCAksGA1UdIASCAkIwggI+MIICOgYJKwYBBAGCNxUvMIICKzBJBggrBgEFBQcCARY9aHR0cHM6Ly93d3cubWl"
      "jcm9zb2Z0LmNvbS9wa2kvc3NsL2Nwcy9NaWNyb3NvZnRNU05Db250ZW50Lmh0bTCCAdwGCCsGAQUFBwICMIIBzh6CAcoATQBpAG"
      "MAcgBvAHMAbwBmAHQAIABkAG8AZQBzACAAbgBvAHQAIAB3AGEAcgByAGEAbgB0ACAAbwByACAAYwBsAGEAaQBtACAAdABoAGEAd"
      "AAgAHQAaABlACAAaQBuAGYAbwByAG0AYQB0AGkAbwBuACAAZABpAHMAcABsAGEAeQBlAGQAIABpAG4AIAB0AGgAaQBzACAAYwBl"
      "AHIAdABpAGYAaQBjAGEAdABlACAAaQBzACAAYwB1AHIAcgBlAG4AdAAgAG8AcgAgAGEAYwBjAHUAcgBhAHQAZQAsACAAbgBvAHI"
      "AIABkAG8AZQBzACAAaQB0ACAAbQBhAGsAZQAgAGEAbgB5ACAAZgBvAHIAbQBhAGwAIABzAHQAYQB0AGUAbQBlAG4AdABzACAAYQ"
      "BiAG8AdQB0ACAAdABoAGUAIABxAHUAYQBsAGkAdAB5ACAAbwByACAAcwBhAGYAZQB0AHkAIABvAGYAIABkAGEAdABhACAAcwBpA"
      "GcAbgBlAGQAIAB3AGkAdABoACAAdABoAGUAIABjAG8AcgByAGUAcwBwAG8AbgBkAGkAbgBnACAAcAByAGkAdgBhAHQAZQAgAGsA"
      "ZQB5AC4AIDALBgNVHQ8EBAMCB4AwgaEGA1UdIwSBmTCBloAUdeBjdZAOPzN4/ah2f6tTCLPcC+qhcqRwMG4xCzAJBgNVBAYTAlV"
      "TMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xGD"
      "AWBgNVBAMTD01TTiBDb250ZW50IFBDQYIKYQlx2AABAAAABTBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsLm1pY3Jvc29md"
      "C5jb20vcGtpL2NybC9wcm9kdWN0cy9NU05Db250ZW50Q0EuY3JsME4GCCsGAQUFBwEBBEIwQDA+BggrBgEFBQcwAoYyaHR0cDov"
      "L3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0L01TTkNvbnRlbnRDQS5jcnQwDQYJKoZIhvcNAQEFBQADggEBAHDQBEIIaOolQ2d"
      "E9BH/5LHdW9r+j2kW5n77eXxVimhSVKrFSPzTSjAdtSt0Co+88nXpcJABZq+v1sIVQLFh79hJyyXes1tokNE4aqdpsI6/Eqzrfs"
      "5LtTxPmGqxPTP5EaEKQTlCX1S7j2hosLAumG6SvrCNWpqNDXk34ZOzMfJkxBAHK85QTzX7vEgQWkCCygS88VkqXO78L2bFk5vw/"
      "vxhqfSBskEmn35U3apsEfzJTm4QPpE+WveskYLZUkg3PTMEpS+53+ZnvAk40rbzJhhdO8lfFCL4RNU9igYa8TiRznuxQ7Fq+Pcl"
      "PGUVa7onZafyGy1zMbIgKWiWX7A5TqIxggGQMIIBjAIBATCBijB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjE"
      "QMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NU04gQ29udGVudCBBdX"
      "RoZW50aWNhdGlvbiBDQQIKBRawKAABAAAACTAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9"
      "w0BCQUxDxcNMDUwMzA3MjAxMTQ4WjAjBgkqhkiG9w0BCQQxFgQUBwu2BOj5y3gX2kZjt+EkLKEnUI4wDQYJKoZIhvcNAQEBBQAE"
      "gYBODy/vmAxlqGaFxjpUop5d3D0biHIFlo2TmnOJBIkRREq4MtKkqjfYLtrNSefGKpxrbqQz2vT78bSedGktHvoqmHwR2F/IzcM"
      "qaANFOJd5MeXbjCloHbYxgK9fcMV0eEYyPRARSQbb1FdkQMeaMxoWJy6q63TD7RAMgcrQeLJobA==\"/>\r\n" ) );
    chat->getChatWindow()->resize( 800, 650 );
    sb4->parseMimeMessage( QStringList()<<"MSG"<<"contact7@kmess.org"<<"%5Bb%5D%5Bc%3D%2333A%5DVale%E2%84%A2%5B%2Fc%3D%233A3%5D%5B%2Fb%5D"<<"1523", winkMessage );
  }

  QTimer *test = new QTimer(this);
  connect(test, SIGNAL(timeout()), this, SLOT(testChatWindowSlot()));
  connect(kmess_->disconnect_, SIGNAL(triggered(bool)), test, SLOT(stop()));
//   test->start( 6000 );
}



void KMessTest::testChatWindowSlot()
{
  if( kmess_->chatMaster_->switchboardConnections_.isEmpty() )
  {
    QTimer *timer = static_cast<QTimer*>( sender() );
    if( timer ) timer->stop();
    return;
  }

  static int i = 0;
//   ContactList *list = kmess_->msnNotificationConnection_->contactList_;
//   list->getContactByHandle( "contact1@kmess.org" )->setPersonalStatus( QString("nuovo pm %1" ).arg( i++) );

//   kmess_->chatMaster_->chats_.first()->slotReceivedNudge( CurrentAccount::instance()->getContactList()->getContactByHandle( "contact1@kmess.org" ) );
//   kmess_->chatMaster_->chats_.first()->contactLeft( CurrentAccount::instance()->getContactList()->getContactByHandle( "contact1@kmess.org" ),false );

  MsnSwitchboardConnection *sb1 = kmess_->chatMaster_->switchboardConnections_.first();
  if( sb1 == 0 )
  {
    // KMess should be quitting...
    return;
  }

  MimeMessage message( QString( "MIME-Version: 1.0\r\nContent-Type: text/plain;charset=UTF-8\r\nX-MMS-IM-Format: FN=Georgia; EF=; CO=c080ff; CS=0; PF=12\r\n\r\nTesting incoming chats %1\r\n" ).arg( i++ ) );

  sb1->parseChatMessage( "contact1@kmess.org", "Contact 1", "", message );
}



void KMessTest::testCrash()
{
  QObject *object = 0;
  object->objectName();
}


void KMessTest::testAddContactDialog()
{
  QString handle;
  QStringList groupsId;
  new AddContactDialog( handle, groupsId );

  kmDebug() << "adding " << handle << "on groups: " << groupsId;
}



void KMessTest::testChallengeHandler()
{
  MSNChallengeHandler handler;
  // Tested with
  // PRODUCT_KEY "ILTXC!4IXB5FB*PX"
  // PRODUCT_ID  "PROD0119GSJUC$18"
  kmDebug() << handler.computeHash( "TEST"); // "299ef8849928ab29512748d378cb93b0"
  kmDebug() << handler.computeHash( "KMessTest"); // "6e7fbd3c1457c4192d18bc9d19ef4e3e"
  kmDebug() << handler.computeHash( "KMessKMessKmess"); // "736d5611bdd0f6f60b93343e169c6192"
}



void KMessTest::testContactAddedUserDialog()
{
  //set up groups to populate listwidget
  testGroupsAndContacts();

  ContactAddedUserDialog *dialog = new ContactAddedUserDialog( "someone@hotmail.com", "SomeNickName" );
  
  dialog->addTab( "someone1@hotmail.com", "SomeNickName1" );

  connect( dialog, SIGNAL( userChoice(const QString&, const QStringList&, const int) ),
           this,   SLOT  ( testContactAddedUserDialogSlot(const QString&, const QStringList&, const int) ) );

  dialog->show();
}


void KMessTest::testContactAddedUserDialogSlot( const QString &handle, const QStringList &groupsId, const int code )
{
  switch( (ContactAddedUserWidget::ReturnCode) code )
  {
    case ContactAddedUserWidget::ADD:
      kmDebug() << "result: Add contact" << handle;
      kmDebug() << "result: Adding in groups" << groupsId;
      break;

    case ContactAddedUserWidget::ALLOW:
      kmDebug() << "result: Allow contact" << handle;
      break;

    case ContactAddedUserWidget::BLOCK:
      kmDebug() << "result: Block contact" << handle;
      break;

    case ContactAddedUserWidget::IGNORE:
      kmDebug() << "result: Ignore request of contact" << handle;
      break;

    default:
      kmDebug() << "result: undefined, contact:" << handle;
      break;
  }
}


void KMessTest::testNotifications()
{
  testGroupsAndContacts();

  ContactList *list = kmess_->msnNotificationConnection_->contactList_;
  Contact *contact1 = list->getContactByHandle( "contact1@kmess.org" );
  Contact *contact2 = list->getContactByHandle( "contact2@kmess.org" );
  Contact *contact3 = list->getContactByHandle( "contact3@kmess.org" );

  contact1->setStatus( STATUS_ONLINE  );
  contact2->setStatus( STATUS_OFFLINE );
  contact3->setStatus( STATUS_BUSY    );

  ContactStatusNotification *cs = new ContactStatusNotification( kmess_->notificationManager_ );
  cs->notify( contact1, true );
  cs->notify( contact2, true );
  cs->notify( contact3, true );
}


void KMessTest::testNowListening()
{
  NowListeningClient *client = new NowListeningClient();
  client->setEnabled( true );
}


void KMessTest::testNotificationConnection()                { quitAfterTest_ = true; }
void KMessTest::testConnect()                               { quitAfterTest_ = true; }
void KMessTest::testSettings()                              { quitAfterTest_ = true; }
void KMessTest::testSwitchboardConnection()                 { quitAfterTest_ = true; }



void KMessTest::testGroupsAndContacts()
{
  CurrentAccount *account = CurrentAccount::instance();

  AccountsManager::instance()->addAccount(account);
  EmoticonManager::instance()->connected();

  account->setLoginInformation("test@test.com", "[b]Testing Account[/b]", "test" );
  account->setPersonalMessage( "omg! this [u]rocks![/u] :D " );
  account->setGuestAccount( true );
  account->setListPictureSize( 32 );
  account->setStatus( STATUS_ON_THE_PHONE );
  account->setStatusOptions( true, 5, true );

  account->setShowContactListBird( true );
  account->setContactListOptions( false, false, true );
  account->setEmailSupported( true );
  account->setContactListDisplayMode( Account::VIEW_MIXED ); // VIEW_MIXED VIEW_BYSTATUS VIEW_BYGROUP
  account->setShowAllowedContacts( false );
  account->setShowEmptyGroups( false );
  account->setShowOfflineContacts( true );
  account->setShowRemovedContacts( false );
  account->setNoEmails( 1000 );

  account->setShowChatUserPicture( true );
  account->setFontInformation( QFont( "Monospace", 16 ), "#FF9900", QFont( "Serif", 12 ), "#99FF00" );
  account->setShowSessionInfo( true );
  account->setChatInformation( true, true, true, true, true, true, true, true, true, true, 0, "Fresh" );
  account->setChatLoggingInformation( true, true, Account::EXPORT_HTML, "/home/valerio/KILLME/logs", Account::BYYEAR );

  ChatHistoryManager::setAccount( account->getHandle() );

  Group *group;
  Contact *contact;
  ContactList *list = kmess_->msnNotificationConnection_->contactList_;

  list->reset( true );

  group = list->addGroup( "friends", "My Friends" );
  group = list->addGroup( "work", "Work Mates" );
  group->setExpanded( false );
  group = list->addGroup( "family", "Family" );
  group = list->addGroup( "empty", "Empty Group");

  list->getGroupById( SpecialGroups::INDIVIDUALS )->setExpanded( false );
//   list->getGroupById( SpecialGroups::OFFLINE )->setExpanded( false );

  contact = list->addContact( "contact1@kmess.org", "Contact 1", 11, QStringList()<<"friends"<<"work", "c1" );
  contact->manageEmoticonBlackList( true, "lol" );
  contact->manageEmoticonBlackList( true, "&lt;aaaa" );
  contact->manageEmoticonBlackList( true, "&#39;aaaasdsdfa" );

  // Pending emoticons
  contact->addEmoticonDefinition( "-pend", "1hashhashhash" );
  contact->addEmoticonDefinition( "-ing", "2shhashhashha" );

  // Received emoticons
  contact->addEmoticonDefinition( "-rece", "3ashhashhashh" );
  contact->addEmoticonDefinition( "-ived", "4hhashhashhas" );
  contact->addEmoticonFile( "3ashhashhashh", KIconLoader::global()->iconPath( "user-online", KIconLoader::Small ) );
  contact->addEmoticonFile( "4hhashhashhas", KIconLoader::global()->iconPath( "user-busy", KIconLoader::Small ) );

  list->changeContactStatus( "contact1@kmess.org", STATUS_ONLINE, "[c=red]Contact 1[/c] :) <one&amp;two!> & three four five six seven", 3, QString(), false );
  contact->setPersonalStatus( "Contact 1 :) -- www.google.it - <sdf> [u]adgdf dfgfsdf sdgf hgegagdsf dfdfg[/u] asd &amp;" );
  contact = list->addContact( "contact2@kmess.org", "Contact 2", 3, QStringList()<<"family", "c2" );
  list->changeContactStatus( "contact2@kmess.org", STATUS_OFFLINE, QString::fromUtf8("انتقدت منظمة حقوقيتقدت منظمة حقوقيتقدت منظمة حقوقيتقدت منظمة حقوقيتقدت منظمة حقوقية"), 3, QString(), false );
  contact = list->addContact( "contact3@kmess.org", "Contact 3", 3, QStringList(), "c3" );
  contact = list->addContact( "contact4@kmess.org", "Contact 4", 3, QStringList(), "c4" );
  list->changeContactStatus( "contact4@kmess.org", STATUS_BUSY, "Contact 4", 3, QString(), false );
  contact = list->addContact( "contact5@kmess.org", "Contact 5", 3, QStringList()<<"work", "c5" );
  list->changeContactStatus( "contact5@kmess.org", STATUS_ON_THE_PHONE, "Contact 5", 3, QString(), false );
  contact->setPersonalStatus( "Contact 5 Status" );
  contact = list->addContact( "contact6@kmess.org", "Contact 6 www.google.it", 3, QStringList()<<"work"<<"friends", "c6" );
  list->changeContactStatus( "contact6@kmess.org", STATUS_OFFLINE, "Contact 6 www.google.it", 3, QString(), false );
  contact = list->addContact( "contact7@kmess.org", "<b> Contact 7 </b>", 3, QStringList()<<"friends", "c7" );
  list->changeContactStatus( "contact7@kmess.org", STATUS_AWAY, "<b> Contact 7 </b>", 1342210084, QString(), false );
  contact->setPersonalStatus( "Contact 7 Status", "Music", "KMess - The KMess Song" );
  contact = list->addContact( "contact8@kmess.org", "Contact 8", 3, QStringList(), "c8" );
  list->changeContactStatus( "contact8@kmess.org", STATUS_ONLINE, "Contact 8", 3, QString(), false );
  contact = list->addContact( "contact9@kmess.org", "Contact 9", 3, QStringList()<<"work", "c9" );
  list->changeContactStatus( "contact9@kmess.org", STATUS_BUSY, "Contact 9", 3, QString(), false );
  contact = list->addContact( "contact10@kmess.org", "Contact 10", 3, QStringList()<<"work", "c10" );
  list->changeContactStatus( "contact10@kmess.org", STATUS_OFFLINE, "Contact 10", 3, QString(), false );
}



void KMessTest::testContactList()
{
  testGroupsAndContacts();

//   ContactList *list = kmess_->msnNotificationConnection_->contactList_;
//   list->dump();

  kmess_->connected();
  kmess_->window()->show();

  // Show the Now Listening field
//   kmess_->view_->changedSong( "White Stripes, The", "Elephant", "Seven Nation Army", true );
  kmess_->view_->slotUpdateEmailDisplay();

  QTimer *test = new QTimer(this);
  connect(test, SIGNAL(timeout()), this, SLOT(testContactListSlot()));
  connect(kmess_->disconnect_, SIGNAL(triggered(bool)), test, SLOT(stop()));
//   test->start( 5000 );
}


// A generic method to use as throwaway slot for delayed code
void KMessTest::testContactListSlot()
{
  kmDebug() << "TEST - Switching contact status";
  ContactList *list = kmess_->msnNotificationConnection_->contactList_;

  static int i=0;
  static bool statusSwitch = true;
  Status first = STATUS_AWAY, second = STATUS_OFFLINE;

/*
  if( i == 1 )
  {
    QTimer *timer = static_cast<QTimer*>( sender() );
    if( timer ) timer->stop();
  }
*/

  if( statusSwitch )
  {
    qSwap( first, second );
  }
  statusSwitch = ! statusSwitch;
  i++;

  if( i == 3 )
    list->addContact( "contact11@kmess.org", "Contact 11", 3, QStringList(), "c11" );
  if( i == 5 )
    list->changeContactStatus( "contact11@kmess.org", STATUS_BE_RIGHT_BACK, "Contact 11", 3, QString(), false );

  list->getContactByHandle( "contact5@kmess.org")->setPersonalStatus( QString("Contact 5 Status: %1").arg( i ), "Music", QString("Chemical Brothers - Got Glint? %1").arg( i ) );
  list->getContactByHandle( "contact8@kmess.org")->setPersonalStatus( QString("Contact 8 Status: %1").arg( i ) );
  list->changeContactStatus( "contact5@kmess.org", first, QString("Contact 5 name #%1").arg( i ), 3, QString(), true );
  list->changeContactStatus( "contact8@kmess.org", second, QString("Contact 8 name #%1").arg( i ), 3, QString(), true );
}



void KMessTest::testMsnPlus()
{
  quitAfterTest_ = true;

  OldRichTextParser::initialize();
  QStringList strings;

  strings << QString::fromUtf8( "[c=#0080FF][u][c=39][b](S) [c=29] Fede  [/c](S)[/b][/c=39] forza azzurriiiiiii[/u][/c]" );
  strings << QString::fromUtf8( "[c=50][a=50]Opera[/a][/c][c=0][a=0]tore ec[/a][/c][c=4][a=4]ologico[/a][/c]" );
  strings << QString::fromUtf8( "[c=4]t[a=#0000]est[/c=44][/a]" );
  strings << QString::fromUtf8( "[c=3]te[a=2]st:)[/a=12]er[/c=4]" );
  strings << QString::fromUtf8( "[a=red]test[a=green]:DeroWithCo[/a=blue]lorssadfasd dfg sdfsdaf sdf [/a=yellow]");
  strings << QString::fromUtf8( "[c=#660000],.-~*'¨¯¨'*·~-.¸-).[i]Simo[/i].(-,.-~*'¨¯¨'*·~-.¸[/c=#00FFF]" );
  strings << QString::fromUtf8( "[b][a=1][c=4]- Emet -:) [/c][/a][/b]" );
  strings << QString::fromUtf8( "[b][a=1][c=10]- :) [T]ester <b>boldExploit</b> :P -[/c][/a][/b]" );
  strings << QString::fromUtf8( "[b][c=green]Vale - New kid on the block! :D[/c=blue][/b]" );
 // strings << QString::fromUtf8( "�$#F37AF0Vanitosa �$ �$#0A79F5Da strega cattiva a principessa..." );
  foreach( QString str, strings )
  {
    QString original( str );
    QString cleaned ( str );
    QString str2    ( str );
    RichTextParser::getCleanString( cleaned );
    RichTextParser::parseMsnString( str, true, true, true, true );
    RichTextParser::getFormattedString( str );
    OldRichTextParser::getCleanString( cleaned );
    OldRichTextParser::parseMsnString( str2, true, true, true, true );
    OldRichTextParser::getFormattedString( str2 );
    KMessageBox::information( kmess_, "<html>" + original + "<br><br>" + cleaned  + "<br><br>" + str  + "<br><br>" + str2 + "</html>" );
  }
}



void KMessTest::benchmarkParser()
{
  quitAfterTest_ = true;

  QString str, str2;
  QStringList strings;
  QTime startTime;
  int i, timeTaken, olds, oldms, news, newms, oldtotal = 0, newtotal = 0;
  const int timesToBenchmark = 50000;
  OldRichTextParser::initialize();
  strings << QString::fromUtf8( "This string contains nothing special, but it is quite long nonetheless. The idea is "
                                "that nothing is changed in this string, so the parser reading efficiency is checked." );
  strings << QString::fromUtf8( "[c=#0080FF][u][c=39][b](S) [c=29] Fede  [/c](S)[/b][/c=39] forza azzurriiiiiii[/u][/c]" );
  strings << QString::fromUtf8( "[b][a=1][c=10]- :) [T]ester <b>boldExploit</b> :P -[/c][/a][/b]" );
  strings << QString::fromUtf8( ":D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D"
                                ":D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D"
                                ":D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D:D" );
  strings << QString::fromUtf8( "This is a looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
                                "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
                                "ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong word" );
  strings << QString::fromUtf8( "http://kmess.org/ http://kmess.org/ http://kmess.org/ http://kmess.org/ http://kmess.org/" );
  strings << QString::fromUtf8( "dazjorz.com javascript.js test.nl http://google.com/ test@example.com");
  strings << QString::fromUtf8( "www.google.com google.com bugs@kmess.org http://www.kmess.org http://www.kmess.org/weird_url-with?random&stuff");
  foreach( QString origstr, strings )
  {
    timeTaken = 0;
    kmDebug() << timesToBenchmark << "times, string:" << origstr;

    startTime = QTime::currentTime();
    for( i = 0; i < timesToBenchmark; ++i )
    {
      str = origstr; // this counts in the benchmark time, of course, but it happens in the other benchmark too.
      OldRichTextParser::parseMsnString( str, true, true, true, true );
    }
    timeTaken = QTime::currentTime().msecsTo( startTime );
    oldtotal += (-timeTaken);
    olds      = (-timeTaken) / 1000;
    oldms     = (-timeTaken) % 1000;
    kmDebug() << "Old parser:" << olds << "s" << oldms << "msec";

    startTime = QTime::currentTime();
    for( i = 0; i < timesToBenchmark; ++i)
    {
      str2 = origstr;
      RichTextParser::parseMsnString( str2, true, true, true, true );
    }
    timeTaken = QTime::currentTime().msecsTo( startTime );
    newtotal += (-timeTaken);
    news      = (-timeTaken) / 1000;
    newms     = (-timeTaken) % 1000;
    kmDebug() << "New parser:" << news << "s" << newms << "msec";

    if( str != str2 )
    {
      kmWarning() << "Result mismatch!";
    }
  }

  kmDebug() << "** Grand Totals: **";
  olds  = oldtotal / 1000;
  oldms = oldtotal % 1000;
  news  = newtotal / 1000;
  newms = newtotal % 1000;
  kmDebug() << "Old parser:" << olds << "s" << oldms << "msec";
  kmDebug() << "New parser:" << news << "s" << newms << "msec";
}



void KMessTest::testMsnPlusInteractive()
{
  static bool initialized = false;

  if( !initialized )
  {
    testGroupsAndContacts();
  }

  static QDialog *dialog = new QDialog(kmess_);
  static QVBoxLayout *verticalLayout = new QVBoxLayout(dialog);
  static QLabel *label = new QLabel("Input string:",dialog);
  static QTextEdit *input = new QTextEdit(dialog);
  static QLabel *oldSourceLabel = new QLabel(dialog);
  static QLabel *oldCleanLabel = new QLabel(dialog);
  static QLabel *oldHtmlLabel = new QLabel(dialog);
  static QLabel *newSourceLabel = new QLabel(dialog);
  static QLabel *newCleanLabel = new QLabel(dialog);
  static QLabel *newHtmlLabel = new QLabel(dialog);

  if( !initialized)
  {
    initialized = true;

    OldRichTextParser::initialize();
    verticalLayout->addWidget(label);
    verticalLayout->addWidget(input);
    verticalLayout->addWidget(oldSourceLabel);
    verticalLayout->addWidget(oldCleanLabel);
    verticalLayout->addWidget(oldHtmlLabel);
    verticalLayout->addWidget(newSourceLabel);
    verticalLayout->addWidget(newCleanLabel);
    verticalLayout->addWidget(newHtmlLabel);
    dialog->setLayout(verticalLayout);

    oldSourceLabel->setTextFormat( Qt::PlainText );
    newSourceLabel->setTextFormat( Qt::PlainText );
    oldSourceLabel->setWordWrap( true );
    oldCleanLabel->setWordWrap( true );
    oldHtmlLabel ->setWordWrap( true );
    newSourceLabel->setWordWrap( true );
    newCleanLabel->setWordWrap( true );
    newHtmlLabel ->setWordWrap( true );
    oldSourceLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
    newSourceLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
    oldSourceLabel->setFrameShape(QFrame::Box);
    newSourceLabel->setFrameShape(QFrame::Box);

    connect( input, SIGNAL( textChanged() ),
             this,  SLOT  ( testMsnPlusInteractive() ) );
    dialog->show();
  }
  else
  {
    QString text;
    QString cleaned, parsed;

    QString handle( "contact1@kmess.org" );
    QStringList pending;
    // CurrentAccount::instance()->getContactByHandle( handle )->getPendingEmoticonPattern();


    // Old parser
    text = input->document()->toPlainText();
    OldRichTextParser::parseMsnString( text, true, true, true, true, "contact1@kmess.org", pending );
    cleaned = parsed = text;

    OldRichTextParser::getCleanString( cleaned );
    OldRichTextParser::getFormattedString( parsed );
    oldSourceLabel->setText( "Old source:  " + cleaned );
    oldCleanLabel->setText( "Old text:  " + cleaned );
    oldHtmlLabel ->setText( "Old HTML:  " + parsed );

    // New parser
    text = input->document()->toPlainText();
    RichTextParser::parseMsnString( text, true, true, true, true, true, "contact1@kmess.org", pending );
    cleaned = parsed = text;

    RichTextParser::getCleanString( cleaned );
    RichTextParser::getFormattedString( parsed );
    newSourceLabel->setText( "New source:  " + cleaned );
    newCleanLabel->setText( "New text:  " + cleaned );
    newHtmlLabel ->setText( "New HTML:  " + parsed );
  }
}


void KMessTest::testSoapConnection()
{
  MsnAppDirectoryService *appDir = new MsnAppDirectoryService();
  appDir->queryServiceList( MsnAppDirectoryService::GAMES );
}



void KMessTest::testSystemTray()
{
  quitAfterTest_ = true;

  kmess_->systemTrayWidget_->displayCloseMessage();
}


void KMessTest::testXslTransformation()
{
  // A simple test using XSL/XML data of the KMess website
  QString wwwRoot( "/srv/www/vhosts/kmess/htdocs" );

  // Load XSL
  XslTransformation *xsl = new XslTransformation();
  xsl->setStylesheet( wwwRoot + "/resources/xsl/kmess.xsl" );

  // Open XML
  QFile file( wwwRoot + "/index.xml" );
  bool open = file.open(QIODevice::ReadOnly);
  if( ! open)
  {
    kmWarning() << "Could not open file: " << file.fileName();
    return;
  }

  // Load XML
  QByteArray fileData = file.readAll();
  QString xml( QString::fromUtf8(fileData.data(), fileData.size()) );
  file.close();

  // Transform XML
  kmDebug() << "XSL transformation result:";
  kmDebug() << xsl->convertXmlString(xml);

  delete xsl;
}



void KMessTest::testOfflineMessages()
{
  // The MSN servers *sometimes* send the offline messages before the contact list.
  // 1. make sure we have an empty contact list
  // 2. receive an offline message from nonexistant@kmess.org
  // 3. add contacts to the contact list
  // 4. receive an offline message from an existing contact

  Account *account = CurrentAccount::instance();
  account->setGuestAccount( true );

  ContactList *list = kmess_->msnNotificationConnection_->contactList_;
  // Don't add any groups or contacts.
  list->reset( true );

  // An offline message sent yesterday, from an unknown user, received before
  // the contact list was ever created
  QString address ("nonexistant@kmess.org");
  ChatMessage message( ChatMessage::TYPE_OFFLINE_INCOMING,
                       ChatMessage::CONTENT_MESSAGE,
                       true,
                       QString("This message should come from the e-mail address ").append(address),
                       address,
                       address,
                       QString(),
                       QFont(),
                       QString(),
                       QDateTime::currentDateTime().addDays( -1 ) );
  kmess_->chatMaster_->showSpecialMessage(message);

  // re-add the contact list
  testGroupsAndContacts();

  // send another offline message
  address = "contact1@kmess.org";

  // emulate some of MsnNotificationConnection::receivedOfflineIm() behaviour.
  const ContactBase *contact = CurrentAccount::instance()->getContactByHandle(address);
  QString name, picture;
  if( contact != 0 )
  {
    name    = contact->getFriendlyName();
    picture = contact->getContactPicturePath();
  }
  else
  {
    name    = "Warning: This message is a bug; the contact should be found in the contact list!";
    picture = QString::null;
  }

  ChatMessage message2( ChatMessage::TYPE_OFFLINE_INCOMING,
                        ChatMessage::CONTENT_MESSAGE,
                        true,
                        QString("This message should come from a proper contact whose name is ").append(name),
                        address,
                        name,
                        picture,
                        QFont(),
                        QString(),
                        QDateTime::currentDateTime().addDays(-1));
  kmess_->chatMaster_->showSpecialMessage(message2);
}


#include "kmesstest.moc"
