/***************************************************************************
 *   Copyright (C) 2007 by Michael Zanetti
 *
 *                                                                         *
 *   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 Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
 ***************************************************************************/


/**
  * @author Michael Zanetti
  */

#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif

#include <tqapplication.h>
#include <tqeventloop.h>

#include <kopetechatsession.h>
#include <kopeteaccount.h>

#include <kdebug.h>
#include <tdemessagebox.h>
#include <kstandarddirs.h>
#include <tdelocale.h>
#include <kanimwidget.h>


#include "otrlconfinterface.h"
#include "otrlchatinterface.h"
#include "otrplugin.h"
#include "privkeypopup.h"



/*********************** Konstruktor/Destruktor **********************/

OtrlConfInterface::OtrlConfInterface( TQWidget *preferencesDialog ){

	this->preferencesDialog = preferencesDialog;

	OTRL_INIT;
	
	userstate = OtrlChatInterface::self()->getUserstate();

	kdDebug() << "OtrlConfInterface created" << endl;
}

OtrlConfInterface::~ OtrlConfInterface(){
	otrl_userstate_free(userstate);
}

/*********************** Functions for kcm module ************************/

TQString OtrlConfInterface::getPrivFingerprint( TQString accountId, TQString protocol){
//	if (otrl_privkey_read(userstate, TQString(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true )) + "privkey" ) == 0){
		char fingerprint[45];
		if( otrl_privkey_fingerprint( userstate, fingerprint, accountId.latin1(), protocol.latin1()) != 0 ){
			return fingerprint;
		}
//	}
	return i18n("No fingerprint present.");
}


bool OtrlConfInterface::hasPrivFingerprint( TQString accountId, TQString protocol ){
	char fingerprint[45];
	if( otrl_privkey_fingerprint( userstate, fingerprint, accountId.latin1(), protocol.latin1() ) != 0 ){
		return true;
	}
	return false;
}


void OtrlConfInterface::generateNewPrivKey( TQString accountId, TQString protocol ){
	PrivKeyPopup *popup = new PrivKeyPopup( preferencesDialog, i18n("Generating private key").utf8(), TQt::WType_Dialog | TQt::WStyle_StaysOnTop );
	KAnimWidget *anim = new KAnimWidget( "kde", 72, popup->animFrame, "kopete" );
	anim->start();
	anim->show();

	popup->setCloseLock( true );
	popup->show();
	KeyGenThread *keyGenThread = new KeyGenThread ( accountId, protocol );
	keyGenThread->start();
	while( !keyGenThread->wait(100) ){
		tqApp->eventLoop()->processEvents(TQEventLoop::ExcludeUserInput | TQEventLoop::ExcludeSocketNotifiers, 100);
	}
	popup->setCloseLock( false );
	popup->close();
}

TQValueList<TQStringList> OtrlConfInterface::readAllFingerprints(){
	ConnContext *context;
	Fingerprint *fingerprint;
	TQStringList entry;
	char hash[45];
	TQValueList<TQStringList> list;

	for( context = userstate->context_root; context != NULL; context = context->next ){
		fingerprint = context->fingerprint_root.next;
		while( fingerprint ){
			entry.clear();
			entry << context->username;

			if( ( context->msgstate == OTRL_MSGSTATE_ENCRYPTED ) && ( context->active_fingerprint != fingerprint ) ){
				entry << i18n("Unused");
			} else {
				if (context && context->msgstate == OTRL_MSGSTATE_ENCRYPTED) {
					if (context->active_fingerprint->trust && context->active_fingerprint->trust[0] != 0) {
						entry << i18n("Private");
					} else {
						entry << i18n("Unverified");
					}
				} else if (context && context->msgstate == OTRL_MSGSTATE_FINISHED) {
					entry << i18n("Finished");
				} else {
					entry << i18n("Not Private");
				}
			}
			entry << ((fingerprint->trust && fingerprint->trust[0]) ? i18n("Yes") : i18n("No"));
			otrl_privkey_hash_to_human( hash, fingerprint->fingerprint );
			entry << hash;
			entry << context->protocol;
			list << entry;
			fingerprint = fingerprint->next;
		}
	}
	return list;
}

void OtrlConfInterface::verifyFingerprint( TQString strFingerprint, bool trust ){
	Fingerprint *fingerprint;

	fingerprint = findFingerprint( strFingerprint );

	if( fingerprint != 0 ){
		if( trust ){
			otrl_context_set_trust( fingerprint, "verified" );
		} else {
			otrl_context_set_trust( fingerprint, NULL );
		}
		kdDebug() << "Writing fingerprints" << endl;
		otrl_privkey_write_fingerprints( userstate, TQString("%1%2").arg(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true )).arg("fingerprints").local8Bit() );
	} else {
		kdDebug() << "could not find fingerprint" << endl;
	}
}

bool OtrlConfInterface::isVerified( TQString strFingerprint ){
	Fingerprint *fingerprint;	

	fingerprint = findFingerprint( strFingerprint.latin1() );

	if( fingerprint->trust && fingerprint->trust[0] ){
		kdDebug() << "found trust" << endl;
		return true;
	} else {
		kdDebug() << "not trusted" << endl;
		return false;
	}
}


void OtrlConfInterface::forgetFingerprint( TQString strFingerprint ){
	Fingerprint *fingerprint;
	
	fingerprint = findFingerprint( strFingerprint );
	otrl_context_forget_fingerprint( fingerprint, 1 );
	otrl_privkey_write_fingerprints( userstate, TQString("%1%2").arg(TDEGlobal::dirs()->saveLocation("data", "kopete_otr/", true )).arg("fingerprints").local8Bit() );
}

Fingerprint *OtrlConfInterface::findFingerprint( TQString strFingerprint ){
//	const char *cFingerprint = ;
//	Fingerprint *fingerprintRoot = &userstate->context_root->fingerprint_root;
	ConnContext *context;
	Fingerprint *fingerprint;
	Fingerprint *foundFingerprint = NULL;
	char hash[45];

	for( context = userstate->context_root; context != NULL; context = context->next ){
		fingerprint = context->fingerprint_root.next;
		while( fingerprint ){
			otrl_privkey_hash_to_human(hash, fingerprint->fingerprint);
			if( strcmp( hash, strFingerprint.latin1()) == 0 ){
				foundFingerprint = fingerprint;
			}
			fingerprint = fingerprint->next;
		}
	}	
	return foundFingerprint;
}

bool OtrlConfInterface::isEncrypted( TQString strFingerprint ){
	Fingerprint *fingerprint;
	Fingerprint *tmpFingerprint;
	Fingerprint *foundFingerprint;
	ConnContext *context;
	ConnContext *foundContext = NULL;

	context = userstate->context_root;

	fingerprint = findFingerprint( strFingerprint );
	for( context = userstate->context_root; context != NULL; context = context->next ){
		tmpFingerprint = context->fingerprint_root.next;
		while( tmpFingerprint ){
			if( tmpFingerprint == fingerprint ){
				kdDebug() << "Found context" << endl;
				foundContext = context;
				foundFingerprint = tmpFingerprint;
			}
			tmpFingerprint = tmpFingerprint->next;
		}
	}

	if( foundContext && foundContext->msgstate != OTRL_MSGSTATE_ENCRYPTED ){
		return false;
	} else if( foundContext && foundFingerprint && foundContext->active_fingerprint == foundFingerprint ){
		return true;
	} else {
		return false;
	}
}
