/***************************************************************************

    supportware
    Copyright (C) 2001-2007 by c.holzheuer
    c.holzheuer@sourceworx.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.

***************************************************************************/


#include <ddwebrelatedmanager.h>
#include <ddconfig.h>
#include <ddthreadmutex.h>
#include <ddwebpage.h>
#include <ddiobuffer.h>
#include <dditemset.h>
#include <ddusermanager.h>
#include <ddmailmanager.h>
#include <ddformchecker.h>
#include <fstream>
#include <ddstringset.h>


/***************************************************************************

    supportware
    Copyright (C) 2001-2007 by c.holzheuer
    c.holzheuer@sourceworx.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.

***************************************************************************/


/**
	Standard constructor. Starts this thread.
*/

ddwebrelatedmanager::ddwebrelatedmanager()
: ddthreadrunnable( "ddwebrelatedmanager" )
{
	
}


/**
	Destructor.
*/

ddwebrelatedmanager::~ddwebrelatedmanager()
{
	//delete _worker??
	get_thread()->exit();
}


/**
	Tabellen und Connection initialisieren.
*/

void ddwebrelatedmanager::init( ddconfig& config, const ddstring& stopwords )
{
	int idx = config.index_of( "relatedlinks" );
	if( idx<0 )
		throw runtime_error( "relatedlinks::init: table config missing" );
	
	_table.connect( config["main"]["connectstring"] );
	_table.init_queries( config[idx] );
	
	_stopwords.from_string( stopwords );
	_evilchars = config["main"]["evilchars"] + '"';
	
	start_thread();
	
}


/**
	Einen Request in der Wait-Queue parken, die Erzeugung der related links passiert aus 
	Performancegründen im Hintergrund.
*/

size_t ddwebrelatedmanager::enqueue_related_query( const ddstring& id, const ddstring& msgsubject, const ddstring& idgrp )
{
	_mutex.lock();
	_queue.push_back( ddwebrelateddata( id, msgsubject, idgrp ) );
 	_mutex.unlock();
	// den worker losscheuchen
	notify();
	return _queue.size();
}


/**
	Process enqueued mails in an endless loop.
*/

void ddwebrelatedmanager::run()
{
  wait();
 
	while( true )
 	{
    if( _queue.empty() )
			wait();
		
		// jemand hat uns aufgeweckt ...
    try
    {
			_mutex.lock();
			// wakeup bug:  sleep again
			if( !_queue.size() ) 
			{
				_mutex.unlock();		
				continue;
			}
			ddwebrelateddata querydata = _queue.front();
  		_queue.pop_front(); 
 			_mutex.unlock();
			if( !querydata.id.empty() && !querydata.msgsubject.empty() )
				create_related_links( querydata.id, querydata.msgsubject, querydata.idgrp );
	
    }
    catch( exception& error )
    {
			// log_fatal crasht die app weil die exception nicht eingefangen werden kann.
			//log_fatal( ddstring( "ddwebrelatedmanager::run(): ") + error.what() );
    	log_error( ddstring( "ddwebrelatedmanager::run(): ") + error.what() );
    }
 	
	} // while


}




/**
	??
*/

void ddwebrelatedmanager::init_searchkey_fuzzy( const ddstring& key, ddstring& query )
{
	ddstringrow words_lower, words_upper, result;
	ddstring cleankey = key.dup().blank_all_of( _evilchars ); 
	words_upper.create_lazy( cleankey );	
	words_lower.create_lazy( cleankey.to_lower() );
	
	// automatisch verunden
	for( size_t i=0; i<words_lower.size(); ++i )
	{
		// stopworte ignorieren
		if( words_lower[i].size() > 2 
			&& !_stopwords.contains_key( words_lower[i] ) 
				)
		{
			result.add( words_upper[i] ); 
			continue;
		}
	}
	if( result.size() == 0 )
		return;
		
	query = result.join( " " );
	
	
}


/**
	??
*/

void ddwebrelatedmanager::init_searchkey_boolean( const ddstring& key, ddstring& query, bool usecaps )
{
	
	ddstringrow words_lower, words_upper, result;
	ddstring cleankey = key.dup().blank_all_of( _evilchars ); 
	words_upper.create_lazy( cleankey );	
	words_lower.create_lazy( cleankey.to_lower() );
	
	// automatisch verunden
	for( size_t i=0; i<words_lower.size(); ++i )
	{
		// stopworte ignorieren
		if( words_lower[i].size() > 2 && !_stopwords.contains_key( words_lower[i] ) )
		{
			if( usecaps && islower( words_upper[i][0] ) )
				continue;
			words_upper[i] = "+" + words_upper[i] + "*";
			result.add( words_upper[i] ); 
			continue;
		}
	}
	if( result.size() == 0 )
		return;
	
	query = result.join( " " );
	
}


/**
	Erzeugt einen Related-Links eintrag.
*/

void ddwebrelatedmanager::create_related_links( const ddstring& id, const ddstring& msgsubject, const ddstring& idgrp )
{
	ddstring key;	
	init_searchkey_fuzzy( msgsubject, key );	
	_table.execute( "create", id, key, idgrp );	
}




