package com.avg.zaap.crashlibrary.core.logger;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.avg.zaap.crashlibrary.CrashLib;

/**
 * This class serves as the basic default logger for the Crash library.
 * <p>
 * Created by marek.osvald on 19.4.2016.
 */
@SuppressWarnings("unused")
public class CrashLogger {

    private static ILogger sCrashLogger = (CrashLib.getConfig() != null) ?
            CrashLib.getConfig().getLogger() : null;

    /**
     * Initialize logger with custom implementation of {@link ILogger}.
     *
     * @param logger to be set as custom one.
     */
    public static void init(ILogger logger) {
        sCrashLogger = logger;
    }

    /**
     * Returns inner logger for setting into another holders of {@link ILogger}.
     *
     * @return set or configured logger, or null if no logger has been set or config has existed.
     */
    public static ILogger getLogger() {
        return sCrashLogger;
    }

    /**
     * Send a VERBOSE log message.
     *
     * @param tag     Used to identify the source of a log message. It usually identifies the class
     *                or activity where the log call occurs.
     * @param message The message you would like logged.
     */
    public static void v(final String tag, final String message) {
        if (sCrashLogger != null) {
            sCrashLogger.v(tag, message);
        }
    }

    /**
     * Send a VERBOSE log message.
     *
     * @param tag    Used to identify the source of a log message. It usually identifies the class
     *               or activity where the log call occurs.
     * @param format formatter string to format by
     * @param args   formatter arguments
     */
    public static void v(final String tag, @NonNull final String format, @Nullable final Object... args) {
        if (sCrashLogger != null) {
            sCrashLogger.v(tag, String.format(format, args));
        }
    }

    /**
     * Send a VERBOSE log message and log the exception.
     *
     * @param tag     Used to identify the source of a log message. It usually identifies the class
     *                or activity where the log call occurs.
     * @param message The message you would like logged.
     * @param tr      An exception to log
     */
    public static void v(final String tag, final String message, final Throwable tr) {
        if (sCrashLogger != null) {
            sCrashLogger.v(tag, message, tr);
        }
    }

    /**
     * Send a DEBUG log message.
     *
     * @param tag     Used to identify the source of a log message. It usually identifies the class
     *                or activity where the log call occurs.
     * @param message The message you would like logged.
     */
    public static void d(final String tag, final String message) {
        if (sCrashLogger != null) {
            sCrashLogger.d(tag, message);
        }
    }

    /**
     * Send a DEBUG log message.
     *
     * @param tag    Used to identify the source of a log message. It usually identifies the class
     *               or activity where the log call occurs.
     * @param format formatter string to format by
     * @param args   formatter arguments
     */
    public static void d(final String tag, @NonNull final String format, @Nullable final Object... args) {
        if (sCrashLogger != null) {
            sCrashLogger.d(tag, String.format(format, args));
        }
    }

    /**
     * Send a DEBUG log message and log the exception.
     *
     * @param tag     Used to identify the source of a log message. It usually identifies the class
     *                or activity where the log call occurs.
     * @param message The message you would like logged.
     * @param tr      An exception to log
     */
    public static void d(final String tag, final String message, final Throwable tr) {
        if (sCrashLogger != null) {
            sCrashLogger.d(tag, message, tr);
        }
    }

    /**
     * Send an INFO log message.
     *
     * @param tag     Used to identify the source of a log message. It usually identifies the class
     *                or activity where the log call occurs.
     * @param message The message you would like logged.
     */
    public static void i(final String tag, final String message) {
        if (sCrashLogger != null) {
            sCrashLogger.i(tag, message);
        }
    }

    /**
     * Send a INFO log message.
     *
     * @param tag    Used to identify the source of a log message. It usually identifies the class
     *               or activity where the log call occurs.
     * @param format formatter string to format by
     * @param args   formatter arguments
     */
    public static void i(final String tag, @NonNull final String format, @Nullable final Object... args) {
        if (sCrashLogger != null) {
            sCrashLogger.i(tag, String.format(format, args));
        }
    }

    /**
     * Send an INFO log message.
     *
     * @param tag     Used to identify the source of a log message. It usually identifies the class
     *                or activity where the log call occurs.
     * @param message The message you would like logged.
     * @param tr      An exception to log
     */
    public static void i(final String tag, final String message, final Throwable tr) {
        if (sCrashLogger != null) {
            sCrashLogger.i(tag, message, tr);
        }
    }

    /**
     * Send a WARN log message.
     *
     * @param tag     Used to identify the source of a log message. It usually identifies the class
     *                or activity where the log call occurs.
     * @param message The message you would like logged.
     */
    public static void w(final String tag, final String message) {
        if (sCrashLogger != null) {
            sCrashLogger.w(tag, message);
        }
    }

    /**
     * Send a WARN log message.
     *
     * @param tag    Used to identify the source of a log message. It usually identifies the class
     *               or activity where the log call occurs.
     * @param format formatter string to format by
     * @param args   formatter arguments
     */
    public static void w(final String tag, @NonNull final String format, @Nullable final Object... args) {
        if (sCrashLogger != null) {
            sCrashLogger.w(tag, String.format(format, args));
        }
    }

    /**
     * Log the exception.
     *
     * @param tag Used to identify the source of a log message. It usually identifies the class or
     *            activity where the log call occurs.
     * @param tr  An exception to log
     */
    public static void w(final String tag, final Throwable tr) {
        if (sCrashLogger != null) {
            sCrashLogger.w(tag, tr);
        }
    }

    /**
     * Send a WARN log message and log the exception.
     *
     * @param tag     Used to identify the source of a log message. It usually identifies the class
     *                or activity where the log call occurs.
     * @param message The message you would like logged.
     * @param tr      An exception to log
     */
    public static void w(final String tag, final String message, final Throwable tr) {
        if (sCrashLogger != null) {
            sCrashLogger.w(tag, message, tr);
        }
    }

    /**
     * Send an ERROR log message.
     *
     * @param tag     Used to identify the source of a log message. It usually identifies the class
     *                or activity where the log call occurs.
     * @param message The message you would like logged.
     */
    public static void e(final String tag, final String message) {
        if (sCrashLogger != null) {
            sCrashLogger.e(tag, message);
        }
    }

    /**
     * Send a ERROR log message.
     *
     * @param tag    Used to identify the source of a log message. It usually identifies the class
     *               or activity where the log call occurs.
     * @param format formatter string to format by
     * @param args   formatter arguments
     */
    public static void e(final String tag, @NonNull final String format, @Nullable final Object... args) {
        if (sCrashLogger != null) {
            sCrashLogger.e(tag, String.format(format, args));
        }
    }

    /**
     * Send a ERROR log message and log the exception.
     *
     * @param tag     Used to identify the source of a log message. It usually identifies the class
     *                or activity where the log call occurs.
     * @param message The message you would like logged.
     * @param tr      An exception to log
     */
    public static void e(final String tag, final String message, final Throwable tr) {
        if (sCrashLogger != null) {
            sCrashLogger.e(tag, message, tr);
        }
    }

    /**
     * What a Terrible Failure: Report a condition that should never happen. The error will always
     * be logged at level ASSERT with the call stack. Depending on system configuration, a report
     * may be added to the DropBoxManager and/or the process may be terminated immediately with an
     * error dialog.
     *
     * @param tag     Used to identify the source of a log message.
     * @param message The message you would like logged.
     */
    public static void wtf(final String tag, final String message) {
        if (sCrashLogger != null) {
            sCrashLogger.wtf(tag, message);
        }
    }

    /**
     * What a Terrible Failure: Report a condition that should never happen. The error will always
     * be logged at level ASSERT with the call stack. Depending on system configuration, a report
     * may be added to the DropBoxManager and/or the process may be terminated immediately with an
     * error dialog.
     *
     * @param tag    Used to identify the source of a log message. It usually identifies the class
     *               or activity where the log call occurs.
     * @param format formatter string to format by
     * @param args   formatter arguments
     */
    public static void wtf(final String tag, @NonNull final String format, @Nullable final Object... args) {
        if (sCrashLogger != null) {
            sCrashLogger.wtf(tag, String.format(format, args));
        }
    }

    /**
     * What a Terrible Failure: Report an exception that should never happen. Similar to
     * wtf(String, String), with an exception to log.
     *
     * @param tag Used to identify the source of a log message.
     * @param tr  An exception to log.
     */
    public static void wtf(final String tag, final Throwable tr) {
        if (sCrashLogger != null) {
            sCrashLogger.wtf(tag, tr);
        }
    }

    /**
     * What a Terrible Failure: Report an exception that should never happen. Similar to
     * wtf(String, Throwable), with a message as well.
     *
     * @param tag     Used to identify the source of a log message.
     * @param message The message you would like logged.
     * @param tr      An exception to log. May be null.
     */
    public static void wtf(final String tag, final String message, final Throwable tr) {
        if (sCrashLogger != null) {
            sCrashLogger.wtf(tag, message, tr);
        }
    }

}
