package market.util;

import java.text.*;
import java.io.*;
//import market.ConfigMarket;

/**
 * This class make logs to PrintWriter.
 * Creation date: (23.2.2000 “. 16:21:27)
 * @author: 
 */
public class LogPrinter {
	
	public final static int NONE = 0;
	public final static int ERROR = 1;
	public final static int INFO = 2;
	public final static int DEBUG = 3;
	public final static int DEBUG_0 = 4;
	public final static int DEBUG_1 = 5;
	public final static int DEBUG_2 = 6;
	public final static int ALL = 7;
	
	protected int curLogLevel;
	protected int curScreenLogLevel;
	
	protected java.io.PrintWriter prnWriter;
	protected java.io.PrintWriter prnWriterOld;
	
	public int SIZE = 100;

	public String logsPath;

	private static long OneDay = 24*3600000;
	public int wait = -1;
	public final static String ext = ".log";
	public final static String EndOfDay = "EOD";
	public final static String StartOfDay = "Start Time: ";
	public String curDate;
/**
 * This is constructor.
 * Creation date: (23.2.2000 “. 16:24:16)
 * @param logLevel int
 * @param screenLogLevel int
 * @param pw java.io.PrintWriter
 */
public LogPrinter( int logLevel, int screenLogLevel, java.io.PrintWriter pw ) {
	super();

	curLogLevel = logLevel;
	curScreenLogLevel = screenLogLevel;

	prnWriter = pw;
}
/**
 * LogPrinter constructor comment.
 */
public LogPrinter( String logsFilePath ) {
	super();

	logsPath = logsFilePath;

	
	
	
}
/**
 * This is constructor.
 * Creation date: (23.2.2000 “. 16:24:16)
 * @param logFilePath java.lang.String
 * @param logLevel int
 * @param screenLogLevel int
 */
public LogPrinter(String logFilePath, int logLevel, int screenLogLevel ) {
	super();
	
	logsPath = logFilePath;
	curLogLevel = logLevel;
	curScreenLogLevel = screenLogLevel;
	
}
/**
 * Create log file.
 * Creation date: (25.2.2000 “. 22:03:19)
 * @return java.io.PrintWriter
 * @param fName java.lang.String
 */
private PrintWriter createLogFile( String fName ) {

	fName = logsPath + File.separatorChar +  fName + ext;
	try {
		File outputFile = new File( fName );
	   	RandomAccessFile out = new RandomAccessFile(outputFile, "rw");
	   	out.seek( outputFile.length() );
		FileDescriptor fd = out.getFD();
	   	
		PrintWriter prnW = new PrintWriter(new BufferedWriter(new FileWriter( fd )));
		prnW.println(StartOfDay + (new java.sql.Time( System.currentTimeMillis()) ).toString() );
		return prnW;
	} catch (Exception e) {
		System.err.println("\nLogPrinter: Can't create new log file: " + fName );
		return null;
	}
}
/**
 * Create log printer from file.
 * Creation date: (25.2.2000 “. 22:03:19)
 * @return market.util.LogPrinter
 * @param logFilePath java.lang.String
 */
public static LogPrinter createLogPrinter( String logFilePath ) {

	PrintWriter out;
	try {
		out = new PrintWriter(new BufferedWriter(new FileWriter( logFilePath )));
	}catch( Exception e ){
		System.out.println("Can't open file: " + logFilePath );
		return null;
	}	

	return new LogPrinter( LogPrinter.NONE, LogPrinter.NONE, out  );
}
/**
 * Call this method before erase object.
 * Creation date: (23.2.2000 “. 21:01:58)
 */
public void destroy() {
	prnWriter.flush();
	prnWriter.close();
	prnWriterOld.flush();
	prnWriterOld.close();
}
/**
 * Gargige colector call this method before erase object.
 * Creation date: (23.2.2000 “. 21:01:58)
 */
protected void finalize() throws Throwable {
	prnWriter.flush();
	prnWriter.close();
	prnWriterOld.flush();
	prnWriterOld.close();
		
	super.finalize();
}
/**
 * Call this method to flush buffer in log file.
 * Creation date: (23.2.2000 “. 21:01:58)
 */
public void flush(){
	prnWriter.flush();
}
/**
 * Return log file from data.
 * Creation date: (27.2.00 18:26:48)
 * @param data java.lang.String
 * @param out java.io.PrintWriter
 */
public void getLogFile( String data, PrintWriter out ) {
	
	LineNumberReader fileIn;
	
	flush();
	
	String fName = logsPath + File.separatorChar + data + ext;
	
	try{		
		fileIn = new LineNumberReader( new FileReader( fName ) );
				
		String lineString= fileIn.readLine();
		
		while (lineString != null){
		  out.println( lineString ); 	
		  lineString= fileIn.readLine();
	  	}
		
		fileIn.close();
	}catch( Exception e ){
	   out.println("Can't get log file: " + fName +" !!!");
	}
	 

}
/**
 * Return current log level.
 * Creation date: (23.2.2000 “. 16:38:50)
 * @return int
 */
public int getLogLevel() {
	return curLogLevel;
}
/**
 * Return current PrintWriter.
 * Creation date: (23.2.2000 “. 16:38:50)
 * @return java.io.PrintWriter
 */
public java.io.PrintWriter getPrintWriter() {
	return prnWriter;
}
/**
 * Return current ScreenLogLevel.
 * Creation date: (23.2.2000 “. 19:26:50)
 * @return int
 */
public int getScreenLogLevel() {
	return curScreenLogLevel;
}
/**
 * Chek for old massage and create new log file for new dey.
 * Creation date: (15.2.00 18:39:41)
 * @param millis long
 */
protected synchronized boolean IsOldMassage( long millis ) {

	String date = (new java.sql.Date( millis )).toString();
	int resComp = curDate.compareTo( date );
	
	if ( 0 == resComp ) {
		if ( wait == 0 ) {
			prnWriterOld.println(EndOfDay);
			prnWriterOld.close();
		}else 
			wait--;
		
		return false;
	}else if ( resComp > 0 ){
		return true;
	}else {
		wait = 2;
		prnWriterOld = prnWriter;
		curDate = date;
		prnWriter = createLogFile( date );
		return false;
	}	
}
/**
 * Write message to log if severityLevel is equal or lower to curLogLevel .
 * Creation date: (23.2.2000 “. 16:48:36)
 * @param msg java.lang.String
 * @param severityLevel int
 */
public void log(String msg, int severityLevel) {
	
	if ((severityLevel > curLogLevel) && (severityLevel > curScreenLogLevel))
		return;
	StringBuffer buffer = new StringBuffer(SIZE);

	// construct prefix for log messages:
	buffer.setLength(0);
	long millis = System.currentTimeMillis(); // time stamp in millis...
	//buffer.append(':');

	buffer.append( (new java.sql.Time( millis ) ).toString() ); // date/time stamp...
	buffer.append(':');
	buffer.append( resolveLogLevel(severityLevel) ); // ...log level...
	buffer.append(':');
	buffer.append(msg); // ...log massage...
	buffer.append(':');
	buffer.append('\n');
	
	if (severityLevel <= curLogLevel) {
		if ( IsOldMassage( millis ) ){
			prnWriterOld.write( buffer.toString() );
		}else{
			prnWriter.write( buffer.toString() );			
		}	
	}
	
	if ( severityLevel <= curScreenLogLevel )
	{
		System.out.print(buffer.toString());		
	}	
}
/**
 * Write message to log if severityLevel is equal or lower to curLogLevel.<tr>
 * If you want save eny Exception in log file use t param. 
 * Creation date: (23.2.2000 “. 16:48:36)
 * @param t Throwable
 * @param msg java.lang.String
 * @param severityLevel int
 */
public void log( Throwable t, String msg, int severityLevel) {

	if ((severityLevel > curLogLevel) && (severityLevel > curScreenLogLevel))
		return;
		
	StringBuffer buffer = new StringBuffer(SIZE);

	// construct prefix for log messages:
	buffer.setLength(0);
	//buffer.append(System.currentTimeMillis()); // time stamp in millis...
	//buffer.append(':');
	buffer.append((new java.sql.Time( System.currentTimeMillis() )).toString()); // date/time stamp...
	buffer.append(':');
	buffer.append( resolveLogLevel(severityLevel) ); // ...log level...
	buffer.append(':');
	buffer.append(msg); // ...log massage...
	buffer.append(':');
	buffer.append(t.toString()); // ...log Throwable name...
	buffer.append(':');
	buffer.append('\n');
	if (severityLevel <= curLogLevel) {
		try {
			// write prefix through to underlying byte stream
			prnWriter.write(buffer.toString());
			// prnWriter.flush();

		} catch (Exception e) {
			System.err.println("\nLogPrinter: Can't write in log file.");
		}
	}
	
	if ( severityLevel <= curScreenLogLevel )
	{
		System.out.print(buffer.toString());		
	}	

}
/**
 * Create log printer from file.
 * Creation date: (25.2.2000 “. 22:03:19)
 * @return market.util.LogPrinter
 * @param logFilePath java.lang.String
 */
public static LogPrinter makeLogPrinter(String logFilePath) {
	
	LogPrinter logPrn = new LogPrinter(logFilePath, LogPrinter.NONE, LogPrinter.NONE);
	String fName = (new java.sql.Date(System.currentTimeMillis())).toString();
	
	logPrn.curDate = fName;
	File path = null ;
	try {
		path = new File(logFilePath);
		path.mkdirs();
	} catch (Exception e) {
		System.err.println("\nLogPrinter: Can't create log file path: " + path + " ! ");
		return null;
	}
	
	PrintWriter prnWriter = logPrn.createLogFile(fName);
	if (null != prnWriter) {
		logPrn.prnWriterOld = prnWriter;
		logPrn.setPrintWriter(prnWriter);
	} else {
		logPrn = null;
	}
	
	return logPrn;
}
/**
 * Convert date to millis from 1970 year.
 * Creation date: (04.2.2000 “. 19:07:18)
 * @return long
 * @param date String
 */
private long mDateInMillis( String date ) {
	java.util.Date date1;
	try{
		date1 = DateFormat.getDateInstance().parse( date );
	}catch( ParseException e ){
		return 0;
	}	
	return date1.getTime();
}
/**
 * Convert log level to string.
 * Creation date: (23.2.2000 “. 20:00:22)
 * @return java.lang.String
 * @param severityLevel int
 */
public String resolveLogLevel(int severityLevel) {
	
	switch (severityLevel){
	  case( NONE ): return "NONE"; 
	  case( ERROR ): return "ERROR"; 
	  case( INFO ): return "INFO"; 
	  case( DEBUG ): return "DEBUG";
	  case( DEBUG_0 ): return "DEBUG_0";	  
	  case( DEBUG_1 ): return "DEBUG_1";	  
	  case( DEBUG_2 ): return "DEBUG_2";	  
	  default : return "NULL";
	}	
}
/**
 * Set current log level.
 * Creation date: (23.2.2000 “. 16:38:50)
 * @param newCurLogLevel int
 */
public void setLogLevel( int logLevel ) {
	curLogLevel = logLevel;
}
/**
 * Set current PrintWriter.
 * Creation date: (23.2.2000 “. 16:38:50)
 * @param newPrnWriter java.io.PrintWriter
 */
public void setPrintWriter( java.io.PrintWriter pw ) {
	prnWriter = pw;
}
/**
 * Set current Screen Log level.
 * Creation date: (23.2.2000 “. 19:26:50)
 * @param newScreenLogLevel int
 */
public void setScreenLogLevel(int newScreenLogLevel) {
	curScreenLogLevel = newScreenLogLevel;
}
}

