/**
 * Copyright (c) 2013, Redsolution LTD. All rights reserved.
 * 
 * This file is part of Xabber project; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License, Version 3.
 * 
 * Xabber 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 GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License,
 * along with this program. If not, see http://www.gnu.org/licenses/.
 */
package com.xabber.android.data;

import java.io.PrintWriter;
import java.io.StringWriter;

import org.jivesoftware.smack.Connection;
import org.xbill.DNS.Options;

import android.content.pm.ApplicationInfo;
import android.util.Log;

/**
 * Manager to write to the log.
 * 
 * @author alexander.ivanov
 * 
 */
public class LogManager implements OnLoadListener {

	private static final boolean log;
	private static final boolean debugable;

	static {
		debugable = (Application.getInstance().getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
		log = debugable && SettingsManager.debugLog();
	};

	private final static LogManager instance;

	static {
		instance = new LogManager(Application.getInstance());
		Application.getInstance().addManager(instance);
	}

	public static LogManager getInstance() {
		return instance;
	}

	private LogManager(Application application) {
	}

	@Override
	public void onLoad() {
		if (log) {
			System.setProperty("smack.debuggerClass",
					"org.jivesoftware.smack.debugger.ConsoleDebugger");
			// "com.xabber.android.data.FileLogDebugger");
			System.setProperty("smack.debugEnabled", "true");
			Connection.DEBUG_ENABLED = true;
			Options.set("verbose");
			Options.set("verbosemsg");
			Options.set("verbosecompression");
			Options.set("verbosesec");
			Options.set("verbosecache");
		}
	}

	static public int dString(String tag, String msg) {
		if (log)
			return Log.d(tag, msg);
		else
			return 0;
	}

	static public int eString(String tag, String msg) {
		if (log)
			return Log.e(tag, msg);
		else
			return 0;
	}

	static public int iString(String tag, String msg) {
		if (log)
			return Log.i(tag, msg);
		else
			return 0;
	}

	static public int wString(String tag, String msg) {
		if (log)
			return Log.w(tag, msg);
		else
			return 0;
	}

	static public int vString(String tag, String msg) {
		if (log)
			return Log.v(tag, msg);
		else
			return 0;
	}

	static public int d(Object obj, String msg) {
		return dString(obj.toString(), msg);
	}

	static public int e(Object obj, String msg) {
		return eString(obj.toString(), msg);
	}

	static public int i(Object obj, String msg) {
		return iString(obj.toString(), msg);
	}

	static public int w(Object obj, String msg) {
		return wString(obj.toString(), msg);
	}

	static public int v(Object obj, String msg) {
		return vString(obj.toString(), msg);
	}

	/**
	 * Print stack trace if log is enabled.
	 * 
	 * @param obj
	 * @param exception
	 */
	public static void exception(Object obj, Exception exception) {
		if (!log)
			return;
		forceException(obj, exception);
	}

	/**
	 * Print stack trace even if log is disabled.
	 * 
	 * @param obj
	 * @param exception
	 */
	public static void forceException(Object obj, Exception exception) {
		System.err.println(obj.toString());
		System.err.println(getStackTrace(exception));
	}

	/**
	 * @param exception
	 * @return stack trace.
	 */
	private static String getStackTrace(Exception exception) {
		final StringWriter result = new StringWriter();
		final PrintWriter printWriter = new PrintWriter(result);
		exception.printStackTrace(printWriter);
		return result.toString();
	}

	public static boolean isDebugable() {
		return debugable;
	}

}
