/*
    Copyright (C) 2012 Bartosz Broda, Jacek Bochenek, Łukasz Biłeńkij, 
    Damian Jaworski, Wojciech Mazur, Dominik Piasecki, Maciej Piasecki, 
    Radosław Ramocki
    
    This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 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 LICENSE and COPYING files for more details.
*/

/// @author Bartosz Broda, bartosz.broda@gmail.com
#ifndef SUPERMATRIX_TOOLS_KBESTD
#define SUPERMATRIX_TOOLS_KBESTD

#include "options.h"
#include "kbestcounter.h"

#include <mysql++/mysql++.h>

namespace kbestd{

struct request
{
	long request_word_id;
	int k;
	std::string word;
	std::string matrix_path;
	std::string msr;

	request()
		: request_word_id(-1)
	{}
};

class KBestServer
{
public:
	KBestServer(const options&opts);

	virtual ~KBestServer();
	/**
	 * Runs the server loop.
	 * The loop consists of two steps:
	 * - processing of requests
	 * - listening on specified port for signal that there are new requests available
	 */
	void Run();

	/**
	  * Removes this instance of kbestd from database.
	  * \return true if nothing wrong happend
	  */
	bool CleanUp();

private:
	std::string determine_path(long matrix_id);

	request SearchForWork();
	/**
	 * Runs a processing loop. KBestServer updates self-status in database
	 * (UpdateMyStatus), searches for work in database (SearchForWork)
	 * and processes request if there are any available.
	 *
	 * Note:
	 *
	 * During the data gathering step the table tagger_requests is locked.
	 * During updating of status the table taggers is locked.
	 * \todo updated description & implementation
	 */
	void ProcessRequests();
	/**
	 * Listen for requests on specified port. The listing is
	 * performed in a synchronous way. This way tagger is sleeping until
	 * web service will notify it that new requests are available.
	 * Time between requests can be long, so after waking up KBestd
	 * needs to check if database connectionwasn't dropped (Connect).
	 * It does this by pinging the database server.
	 */
	void Listen();
	/**
	 * Updates status of this instance of KBestServer in database
	 * This method does not assume that information about this instance are already present
	 * in the database, so it is safe to call this method at the beginning of processing. In that cases
	 * the status of this instance will be inserted into taggers table.
	 */
	void UpdateMyStatus(bool ready);
	/// connect to db
	void Connect();
	/// connection object
	mysqlpp::Connection connection_;
	/// options
	const options & opts_;

	KBestCounter counter_;

	long processing_id_;

};

} // ns kbestd

#endif //SUPERMATRIX_TOOLS_KBESTD
