#ifndef DIPL_LOGh
#define DIPL_LOGh 1


enum client_type { cli_orig, cli_emule, cli_other };

/// this struct holds all UDP traffic information
struct udp_stats {
    int got_bytes;
    int got_packets;
    
    int sent_bytes;
    int sent_packets;
    
    int got_0x96;
    int got_0x96_bytes;
    int got_0x97;
    int got_0x97_bytes;
    int got_0x98;
    int got_0x98_bytes;
    int got_0x9a;
    int got_0x9a_bytes;
    int got_0x9c;
    int got_0x9c_bytes;
    int got_0xa0;
    int got_0xa0_bytes;
    int got_0xa1;
    int got_0xa1_bytes;
    int got_0xa2;
    int got_0xa2_bytes;
    int got_0xa3;
    int got_0xa3_bytes;
    int got_0xa4;
    int got_0xa4_bytes;
    
    int got_unknown;
    int got_unknown_bytes;
    
    int sent_0x96;
    int sent_0x96_bytes;
    int sent_0x97;
    int sent_0x97_bytes;
    int sent_0x99;
    int sent_0x99_bytes;
    int sent_0x9b;
    int sent_0x9b_bytes;
    int sent_0x9e;
    int sent_0x9e_bytes;
    int sent_0xa0;
    int sent_0xa0_bytes;
    int sent_0xa1;
    int sent_0xa1_bytes;
    int sent_0xa2;
    int sent_0xa2_bytes;
    int sent_0xa3;
    int sent_0xa3_bytes;
    int sent_0xa4;
    int sent_0xa4_bytes;
    
    int hash_search_successful;
    int hash_search_results;
    
    int text_search_successful;
    int text_search_results;
    
    void *rw_lock;
};



/// this struct holds all TCP traffic information
struct tcp_stats {
    int got_messages;
    int got_bytes;
    
    int sent_messages;
    int sent_bytes;
    
    int got_0x01;
    int got_0x01_bytes;
    int got_0x14;
    int got_0x14_bytes;
    int got_0x15;
    int got_0x15_bytes;
    int got_0x16;
    int got_0x16_bytes;
    int got_0x19;
    int got_0x19_bytes;
    int got_0x1c;
    int got_0x1c_bytes;
    
    int got_unknown;
    int got_unknown_bytes;
    
    int sent_0x32;
    int sent_0x32_bytes;
    int sent_0x33;
    int sent_0x33_bytes;
    int sent_0x34;
    int sent_0x34_bytes;
    int sent_0x35;
    int sent_0x35_bytes;
    int sent_0x36;
    int sent_0x36_bytes;
    int sent_0x38;
    int sent_0x38_bytes;
    int sent_0x40;
    int sent_0x40_bytes;
    int sent_0x41;
    int sent_0x41_bytes;
    int sent_0x42;
    int sent_0x42_bytes;
    
    int hash_search_successful;
    int hash_search_results;
    
    int text_search_successful;
    int text_search_results;
};


/// The base class for all logging classes. ClientLogClass and ServerLogClass are derived from 
/// this one. This is an abstract class.
class BaseLogClass
{
    protected: 
	struct tcp_stats   tcp_stat;                      ///< TCP statistics of client and server.
	unsigned int       shared_files_count;            ///< The number of all shared files.
	unsigned int       all_files_published;           ///< The number of all publishes, incl. doubles. Unused.
	unsigned int       differ_files_count;            ///< The number of all different shared files.
	double             shared_files_size;             ///< The size of all shared files together. 


    public: 
	BaseLogClass() {};                                ///< Empty constructor.
	virtual ~BaseLogClass() {};                       ///< Empty destructor.

	virtual void  LogTcpIn(class sPacket*);           ///< log size of incoming TCP traffic.
	virtual void  LogTcpOut(int, int);                ///< log size of outgoing TCP traffic.
	void          CountSrcSearch(int);                ///< Log query sources search and results found. 
	void          CountTxtSearch(int);                ///< Log text search and results found.
};


/// The ClientLogClass extends the BaseLogClass with the things neccessary for logging client
/// connections. 
class ClientLogClass : public BaseLogClass
{
    private:
	class ServerLogClass   *ServerLogObj;    ///< Reference to the server logging object.
	class sServer          *my_server;            ///< Reference to the sServer class object of the parent connection

	void write_exit_log();                        ///< If an instance of this is destroyed, this should be called beforehand
	                                              ///< to save the logging data. This is done within the destructor.
	void  LF_timestamp(FILE *, char *);           ///< Writes the current time plus an optional string into a log file.
	void  LF_user_info(FILE *);                   ///< Writes information about current user into logfile.

    public:
	virtual ~ClientLogClass();
	ClientLogClass(class ServerLogClass*, class sServer*);   
	                                              ///< a reference to the central
                                                      ///< log object and to the holding sServer class are passed here

	void LogTcpIn(class sPacket *);               ///< Calls parent LogTcpIn and the server object's LogTcpIn.
	void LogTcpOut(int, int);                     ///< Calls parent LogTcpOut and the server object's LogTcpOut.
	void LogSrcSearch(const tHash, int);          ///< Call serverl log function for this and CountSrcSearch().
	void LogTxtSearch(const tHash, int);          ///< Call serverl log function for this and CountSrcSearch().
}; 


/**
   This class extends BaseLogClass with several server-logging-only needed 
   functions / members, as log file handlers, UDP traffic logging functions, regular logging functions, 
   and another exit logger.
*/
class ServerLogClass : public BaseLogClass 
{
    private:
	struct udp_stats   udp_stat;                  ///< The server part's UDP traffic statistics.
	
    public:
	
	// the log files

	FILE *lf_reg_sum;               ///< for regular summaries
	FILE *lf_reg_det;               ///< for regular more detailed summaries
	FILE *lf_user_logoff;           ///< for the user statistics - every user logoff is logged here
	
	FILE *lf_src_searches;          ///< searches are logged here
	FILE *lf_txt_searches;          ///< searches are logged here

	//FILE *lf_trace;                 ///< for logging *everything* 
	//FILE *lf_unknown_tcp;           ///< unknown tcp packets
	//FILE *lf_unknown_udp;           ///< unknown udp packets
	//FILE *lf_userevents;            ///< user events. for future use maybe :-)
	//FILE *lf_files;                 ///< published files are logged in this

	
	// some log control variables 
	
	int  log_min_online_time;


	// member functions & constructor & destructor

	~ServerLogClass();
	ServerLogClass();

	void  LogSrcSearch(const tHash, int);         ///< Call server log function for this and CountSrcSearch().
	void  LogTxtSearch(const tHash, int);         ///< Call server log function for this and CountSrcSearch().
	void  LogUdpIn(int, int);                     ///< Logs incoming UDP traffic.    
	void  LogUdpOut(int, int);                    ///< Logs outgoing UDP traffic.
	
		
	void  write_event_regular();                  ///< writes traffic stats in a summarized manner into the log files
	void  write_exit_log();                       ///< if the server exits, this writes all log data to a file.
};



unsigned int 
get_time();

void 
write_timestamp(FILE *, char *);


#endif

