//
// CRAM: CREATE Real-time Applications Manager
// See the copyright and acknowledgment of authors in the file COPYRIGHT
//
//// Logger.h: the CRAM log file class ////
//

#ifndef __CRAM_LOG_H__
#define __CRAM_LOG_H__

#include "CRAM.h"
//#include "Program.h"
#include <fstream.h>
#include <stdarg.h> 	// for va_arg, va_list, etc.
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

using namespace std;

namespace cram {

typedef enum {					// Enumeration for log message severity level
	kLogInfo,
	kLogImportant,
	kLogWarning,
	kLogError,
	kLogFatal
} LogLevel;

class Logger {

protected:
	char * mLogName;				// my name
	FILE * mLogStream;				// my output stream (to a file) (or Null)

	char * mCache;					// used for real-time systems
	unsigned mPosition;				// virtual cache seek position
	unsigned mIndex;				// real cache write position

	int mSocket;					// output socket (or 0) to manager
	struct sockaddr_in mClient;		// socket "client" (i.e., manager) address
	char mMessage[CRAM_MAX_MSG];	// message buffer storage for socket logging
	
	char * time_string();			// Answer a time string, without the annoying \n that ctime() appends
									// Logger has its own safe send method
	int safe_send(int ssoc, char * buf, unsigned ssiz, struct sockaddr * scln);
	
public:
	unsigned mLevel;				// logging level of verbosity (public for easy access)
									// 		0 = quiet (only fatal errors logged)
									//		default = 3 = verbose
									// 		4 = very verbose socket and thread debugging
	bool mLogToStdout;				// whether to echo all logging to stdout
	bool mLogToSocket;				// whether to echo all logging to a socket (to the manager)
	bool mLogToFile;				// whether to echo all logging to a file (the default)
	unsigned mCacheLen;				// in-memory cache size and storage

	Logger(const char * filename);	// Constructors
	~Logger();
	
	void open();
	void close();
	void set_name(const char * name);
	void set_socket(int sock, sockaddr_in client);

						// printf-style writing
	void log_msg(char * format, ...);	
	void vlog_msg(char* format, va_list args);
	void log_msg(LogLevel level, char* format, ...);
	void vlog_msg(LogLevel level, char* format, va_list args);
	
						// get the tail of the logging text
	int get_text(char * dest, unsigned maxChars);
	int get_text_after(char * dest, unsigned position);
	
	int truncate_file(unsigned maxChars);
};

}

#endif

