module yamalib.log.performancelog;

private import std.stream;
private import std.string;
private import std.date;
private import std.utf;
private import std.regexp;

private import yamalib.auxil.properties;
private import y4d_timer.timer;

/**
	パフォーマンス用にファイルログをとる
	このクラスはスレッドセーフでないので、使用しないこと
*/
class PerformanceLog {
	
	/// ログ出力ファイル名
	package static const char[] LOG_FILENAME = "./log/PerformanceLog.txt";
	/// ファイル読み込み接頭辞
	package static const char[] LOG_FILE_READ = "[FILE_READ]-- ";
	/// アーカイブファイル読み込み接頭辞
	package static const char[] LOG_FILE_READ_ARC = "[FILE_READ_ARC]-- ";
	/// ファイル書き出し接頭辞
	package static const char[] LOG_FILE_WRITE = "[FILE_WRITE]-- ";
	/// テクスチャ生成接頭辞
	package static const char[] LOG_TEXTURE = "[LOAD_TXTURE]-- ";
	/// KGAテクスチャ生成接頭辞
	package static const char[] LOG_TEXTURE_KGA = "[LOAD_TEXTURE_KGA]-- ";
	/// サウンド読み込み生成接頭辞
	package static const char[] LOG_SOUND = "[LOAD_SOUND]-- ";

	/// ログ出力フラグ
	private static bool LOG_OUT_FLG = false;
	

	/// 静的コンストラクタ
	static this() {
		timer = new Timer();
	}
	
	/// 静的デストラクタ
	static ~this() {
		if (logFile !is null && logFile.isOpen() ) {
			logFile.close();
		}
	}
	
	/// 初期化処理
	static void onInit() {
		Properties prop = Properties.getInstance(cast(char[]) "setting.txt");
//		prop.load("setting.txt");
		LOG_OUT_FLG = prop.getPropertyNum(cast(char[]) "log_out", 0) == 1;

		// 新規書き出し
		logFile = new File(LOG_FILENAME, FileMode.OutNew);
		// タイマ
	}
	
	/// 素のパフォーマンス測定	
	static void logRW(char[] option) {
		if (!LOG_OUT_FLG) return;
		
		if ( option is null ) {
			option = cast(char[]) "NO_MESSAGE";
		}

		message = option ~ " ";
		logging = true;
		timer.reset();
	}

	/// テクスチャーロードログ
	static void logTextureLoad( char[] filename, char[] option ) {
		if (!LOG_OUT_FLG) return;
		
		if ( filename is null ) return;
		
		logRW( formatMessage(cast(char[]) LOG_TEXTURE, filename, option) );
	}
	
	/// KGAテクスチャーロードログ
	static void logSoundLoadKGA( char[] filename, char[] option ) {
		if (!LOG_OUT_FLG) return;
		
		if ( filename is null ) return;
		
		logRW( formatMessage(cast(char[]) LOG_TEXTURE_KGA, filename, option) );
	}

	/// サウンドロードログ
	static void logSoundLoad( char[] filename, char[] option ) {
		if (!LOG_OUT_FLG) return;
		
		if ( filename is null ) return;
		
		logRW( formatMessage(cast(char[]) LOG_SOUND, filename, option) );
	}

	/// ファイル読み込みログ	
	static void logFileRead( char[] filename, char[] option ) {
		if (!LOG_OUT_FLG) return;
		
		if ( filename is null ) return;
		
		logRW( formatMessage(cast(char[]) LOG_FILE_READ, filename, option) );
	}

	/// ファイル読み込みログ	
	static void logFileReadArc( char[] filename, char[] option ) {
		if (!LOG_OUT_FLG) return;
		
		if ( filename is null ) return;
		
		logRW( formatMessage(cast(char[]) LOG_FILE_READ_ARC, filename, option) );
	}
	
	/// 最新のログ計測を中止する
	static void abort() {
		if (!LOG_OUT_FLG) return;
		
		if (logging) {
			logging = false;
		}
	}
	
	/// ログ記録
	static void endLog() {
		if (!LOG_OUT_FLG) return;
		
		if ( logging ) {
			
			if ( this.message[length-1] == '\n' ) {
				this.message.length = this.message.length - 1;
			}
			
			this.message ~= std.string.toString( timer.get() ) ~ "ms";
			innerPrint( message );
			logging = false;
		}
	}
	
	/**
	   コンソールに出力するかどうかを設定します
	   */
	static void setPrintConsorl(bool b) {
		printConsorl = b;
	}
	

protected:

	static std.stream.File logFile;
	static Timer timer;
	static char[] message;
	static bool printConsorl = false;
	static bool logging;
	
	/// プリント処理
	static void innerPrint(char[] strMessage) {
		if (strMessage is null) return;

		logFile.writeLine( strMessage );

		if (printConsorl) {
			printf( cast(char*) (strMessage ~ "\n") );
		}
	}
	
	/// ログテキストのフォーマット
	static char[] formatMessage( char[] prefix, char[] filename, char[] option ) {
		if ( logging ) {
			printf("logging fault! %*s\n", message);
		}

		char[] str = null;
		str = prefix ~ "[" ~ filename ~ "]  ";
		
		if ( !(option is null) ) {
			str ~= "[" ~ option ~ "]  ";
		}
		
		return str;
	}
	
	


}