// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.base;

import org.chromium.base.annotations.RemovableInRelease;

import java.util.Locale;

/**
 * Utility class for Logging.
 *
 * <p>
 * Defines logging access points for each feature. They format and forward the logs to
 * {@link android.util.Log}, allowing to standardize the output, to make it easy to identify
 * the origin of logs, and enable or disable logging in different parts of the code.
 * </p>
 * <p>
 * Usage documentation: {@code //docs/android_logging.md}.
 * </p>
 */
public class Log {
    /** Convenience property, same as {@link android.util.Log#ASSERT}. */
    public static final int ASSERT = android.util.Log.ASSERT;

    /** Convenience property, same as {@link android.util.Log#DEBUG}. */
    public static final int DEBUG = android.util.Log.DEBUG;

    /** Convenience property, same as {@link android.util.Log#ERROR}. */
    public static final int ERROR = android.util.Log.ERROR;

    /** Convenience property, same as {@link android.util.Log#INFO}. */
    public static final int INFO = android.util.Log.INFO;

    /** Convenience property, same as {@link android.util.Log#VERBOSE}. */
    public static final int VERBOSE = android.util.Log.VERBOSE;

    /** Convenience property, same as {@link android.util.Log#WARN}. */
    public static final int WARN = android.util.Log.WARN;

    private static final String sTagPrefix = "cr_";
    private static final String sDeprecatedTagPrefix = "cr.";

    private Log() {
        // Static only access
    }

    /** Returns a formatted log message, using the supplied format and arguments.*/
    private static String formatLog(String messageTemplate, Object... params) {
        if (params != null && params.length != 0) {
            messageTemplate = String.format(Locale.US, messageTemplate, params);
        }

        return messageTemplate;
    }

    /**
     * Returns a normalized tag that will be in the form: "cr_foo". This function is called by the
     * various Log overrides. If using {@link #isLoggable(String, int)}, you might want to call it
     * to get the tag that will actually be used.
     * @see #sTagPrefix
     */
    public static String normalizeTag(String tag) {
        if (tag.startsWith(sTagPrefix)) return tag;

        // TODO(dgn) simplify this once 'cr.' is out of the repo (http://crbug.com/533072)
        int unprefixedTagStart = 0;
        if (tag.startsWith(sDeprecatedTagPrefix)) {
            unprefixedTagStart = sDeprecatedTagPrefix.length();
        }

        return sTagPrefix + tag.substring(unprefixedTagStart, tag.length());
    }

    /**
     * Returns a formatted log message, using the supplied format and arguments.
     * The message will be prepended with the filename and line number of the call.
     */
    private static String formatLogWithStack(String messageTemplate, Object... params) {
        return "[" + getCallOrigin() + "] " + formatLog(messageTemplate, params);
    }

    /**
     * Convenience function, forwards to {@link android.util.Log#isLoggable(String, int)}.
     *
     * Note: Has no effect on whether logs are sent or not. Use a method with
     * {@link RemovableInRelease} to log something in Debug builds only.
     */
    public static boolean isLoggable(String tag, int level) {
        return android.util.Log.isLoggable(tag, level);
    }

    /**
     * Sends a {@link android.util.Log#VERBOSE} log message.
     *
     * For optimization purposes, only the fixed parameters versions are visible. If you need more
     * than 7 parameters, consider building your log message using a function annotated with
     * {@link RemovableInRelease}.
     *
     * @param tag Used to identify the source of a log message. Might be modified in the output
     *            (see {@link #normalizeTag(String)})
     * @param messageTemplate The message you would like logged. It is to be specified as a format
     *                        string.
     * @param args Arguments referenced by the format specifiers in the format string. If the last
     *             one is a {@link Throwable}, its trace will be printed.
     */
    private static void verbose(String tag, String messageTemplate, Object... args) {
        String message = formatLogWithStack(messageTemplate, args);
        Throwable tr = getThrowableToLog(args);
        if (tr != null) {
            android.util.Log.v(normalizeTag(tag), message, tr);
        } else {
            android.util.Log.v(normalizeTag(tag), message);
        }
    }

    /** Sends a {@link android.util.Log#VERBOSE} log message. 0 args version. */
    @RemovableInRelease
    @VisibleForTesting
    public static void v(String tag, String message) {
        verbose(tag, message);
    }

    /** Sends a {@link android.util.Log#VERBOSE} log message. 1 arg version. */
    @RemovableInRelease
    @VisibleForTesting
    public static void v(String tag, String messageTemplate, Object arg1) {
        verbose(tag, messageTemplate, arg1);
    }

    /** Sends a {@link android.util.Log#VERBOSE} log message. 2 args version */
    @RemovableInRelease
    @VisibleForTesting
    public static void v(String tag, String messageTemplate, Object arg1, Object arg2) {
        verbose(tag, messageTemplate, arg1, arg2);
    }

    /** Sends a {@link android.util.Log#VERBOSE} log message. 3 args version */
    @RemovableInRelease
    @VisibleForTesting
    public static void v(
            String tag, String messageTemplate, Object arg1, Object arg2, Object arg3) {
        verbose(tag, messageTemplate, arg1, arg2, arg3);
    }

    /** Sends a {@link android.util.Log#VERBOSE} log message. 4 args version */
    @RemovableInRelease
    @VisibleForTesting
    public static void v(String tag, String messageTemplate, Object arg1, Object arg2, Object arg3,
            Object arg4) {
        verbose(tag, messageTemplate, arg1, arg2, arg3, arg4);
    }

    /** Sends a {@link android.util.Log#VERBOSE} log message. 5 args version */
    @RemovableInRelease
    @VisibleForTesting
    public static void v(String tag, String messageTemplate, Object arg1, Object arg2, Object arg3,
            Object arg4, Object arg5) {
        verbose(tag, messageTemplate, arg1, arg2, arg3, arg4, arg5);
    }

    /** Sends a {@link android.util.Log#VERBOSE} log message. 6 args version */
    @RemovableInRelease
    @VisibleForTesting
    public static void v(String tag, String messageTemplate, Object arg1, Object arg2, Object arg3,
            Object arg4, Object arg5, Object arg6) {
        verbose(tag, messageTemplate, arg1, arg2, arg3, arg4, arg5, arg6);
    }

    /** Sends a {@link android.util.Log#VERBOSE} log message. 7 args version */
    @RemovableInRelease
    @VisibleForTesting
    public static void v(String tag, String messageTemplate, Object arg1, Object arg2, Object arg3,
            Object arg4, Object arg5, Object arg6, Object arg7) {
        verbose(tag, messageTemplate, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
    }

    /**
     * Sends a {@link android.util.Log#DEBUG} log message.
     *
     * For optimization purposes, only the fixed parameters versions are visible. If you need more
     * than 7 parameters, consider building your log message using a function annotated with
     * {@link RemovableInRelease}.
     *
     * @param tag Used to identify the source of a log message. Might be modified in the output
     *            (see {@link #normalizeTag(String)})
     * @param messageTemplate The message you would like logged. It is to be specified as a format
     *                        string.
     * @param args Arguments referenced by the format specifiers in the format string. If the last
     *             one is a {@link Throwable}, its trace will be printed.
     */
    private static void debug(String tag, String messageTemplate, Object... args) {
        String message = formatLogWithStack(messageTemplate, args);
        Throwable tr = getThrowableToLog(args);
        if (tr != null) {
            android.util.Log.d(normalizeTag(tag), message, tr);
        } else {
            android.util.Log.d(normalizeTag(tag), message);
        }
    }

    /** Sends a {@link android.util.Log#DEBUG} log message. 0 args version. */
    @RemovableInRelease
    @VisibleForTesting
    public static void d(String tag, String message) {
        debug(tag, message);
    }

    /** Sends a {@link android.util.Log#DEBUG} log message. 1 arg version. */
    @RemovableInRelease
    @VisibleForTesting
    public static void d(String tag, String messageTemplate, Object arg1) {
        debug(tag, messageTemplate, arg1);
    }
    /** Sends a {@link android.util.Log#DEBUG} log message. 2 args version */
    @RemovableInRelease
    @VisibleForTesting
    public static void d(String tag, String messageTemplate, Object arg1, Object arg2) {
        debug(tag, messageTemplate, arg1, arg2);
    }
    /** Sends a {@link android.util.Log#DEBUG} log message. 3 args version */
    @RemovableInRelease
    @VisibleForTesting
    public static void d(
            String tag, String messageTemplate, Object arg1, Object arg2, Object arg3) {
        debug(tag, messageTemplate, arg1, arg2, arg3);
    }

    /** Sends a {@link android.util.Log#DEBUG} log message. 4 args version */
    @RemovableInRelease
    @VisibleForTesting
    public static void d(String tag, String messageTemplate, Object arg1, Object arg2, Object arg3,
            Object arg4) {
        debug(tag, messageTemplate, arg1, arg2, arg3, arg4);
    }

    /** Sends a {@link android.util.Log#DEBUG} log message. 5 args version */
    @RemovableInRelease
    @VisibleForTesting
    public static void d(String tag, String messageTemplate, Object arg1, Object arg2, Object arg3,
            Object arg4, Object arg5) {
        debug(tag, messageTemplate, arg1, arg2, arg3, arg4, arg5);
    }

    /** Sends a {@link android.util.Log#DEBUG} log message. 6 args version */
    @RemovableInRelease
    @VisibleForTesting
    public static void d(String tag, String messageTemplate, Object arg1, Object arg2, Object arg3,
            Object arg4, Object arg5, Object arg6) {
        debug(tag, messageTemplate, arg1, arg2, arg3, arg4, arg5, arg6);
    }

    /** Sends a {@link android.util.Log#DEBUG} log message. 7 args version */
    @RemovableInRelease
    @VisibleForTesting
    public static void d(String tag, String messageTemplate, Object arg1, Object arg2, Object arg3,
            Object arg4, Object arg5, Object arg6, Object arg7) {
        debug(tag, messageTemplate, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
    }

    /**
     * Sends an {@link android.util.Log#INFO} log message.
     *
     * @param tag Used to identify the source of a log message. Might be modified in the output
     *            (see {@link #normalizeTag(String)})
     * @param messageTemplate The message you would like logged. It is to be specified as a format
     *                        string.
     * @param args Arguments referenced by the format specifiers in the format string. If the last
     *             one is a {@link Throwable}, its trace will be printed.
     */
    @VisibleForTesting
    public static void i(String tag, String messageTemplate, Object... args) {
        String message = formatLog(messageTemplate, args);
        Throwable tr = getThrowableToLog(args);
        if (tr != null) {
            android.util.Log.i(normalizeTag(tag), message, tr);
        } else {
            android.util.Log.i(normalizeTag(tag), message);
        }
    }

    /**
     * Sends a {@link android.util.Log#WARN} log message.
     *
     * @param tag Used to identify the source of a log message. Might be modified in the output
     *            (see {@link #normalizeTag(String)})
     * @param messageTemplate The message you would like logged. It is to be specified as a format
     *                        string.
     * @param args Arguments referenced by the format specifiers in the format string. If the last
     *             one is a {@link Throwable}, its trace will be printed.
     */
    @VisibleForTesting
    public static void w(String tag, String messageTemplate, Object... args) {
        String message = formatLog(messageTemplate, args);
        Throwable tr = getThrowableToLog(args);
        if (tr != null) {
            android.util.Log.w(normalizeTag(tag), message, tr);
        } else {
            android.util.Log.w(normalizeTag(tag), message);
        }
    }

    /**
     * Sends an {@link android.util.Log#ERROR} log message.
     *
     * @param tag Used to identify the source of a log message. Might be modified in the output
     *            (see {@link #normalizeTag(String)})
     * @param messageTemplate The message you would like logged. It is to be specified as a format
     *                        string.
     * @param args Arguments referenced by the format specifiers in the format string. If the last
     *             one is a {@link Throwable}, its trace will be printed.
     */
    @VisibleForTesting
    public static void e(String tag, String messageTemplate, Object... args) {
        String message = formatLog(messageTemplate, args);
        Throwable tr = getThrowableToLog(args);
        if (tr != null) {
            android.util.Log.e(normalizeTag(tag), message, tr);
        } else {
            android.util.Log.e(normalizeTag(tag), message);
        }
    }

    /**
     * What a Terrible Failure: Used for conditions that should never happen, and logged at
     * the {@link android.util.Log#ASSERT} level. Depending on the configuration, it might
     * terminate the process.
     *
     * @see android.util.Log#wtf(String, String, Throwable)
     *
     * @param tag Used to identify the source of a log message. Might be modified in the output
     *            (see {@link #normalizeTag(String)})
     * @param messageTemplate The message you would like logged. It is to be specified as a format
     *                        string.
     * @param args Arguments referenced by the format specifiers in the format string. If the last
     *             one is a {@link Throwable}, its trace will be printed.
     */
    @VisibleForTesting
    public static void wtf(String tag, String messageTemplate, Object... args) {
        String message = formatLog(messageTemplate, args);
        Throwable tr = getThrowableToLog(args);
        if (tr != null) {
            android.util.Log.wtf(normalizeTag(tag), message, tr);
        } else {
            android.util.Log.wtf(normalizeTag(tag), message);
        }
    }

    /** Handy function to get a loggable stack trace from a Throwable. */
    public static String getStackTraceString(Throwable tr) {
        return android.util.Log.getStackTraceString(tr);
    }

    private static Throwable getThrowableToLog(Object[] args) {
        if (args == null || args.length == 0) return null;

        Object lastArg = args[args.length - 1];

        if (!(lastArg instanceof Throwable)) return null;
        return (Throwable) lastArg;
    }

    /** Returns a string form of the origin of the log call, to be used as secondary tag.*/
    private static String getCallOrigin() {
        StackTraceElement[] st = Thread.currentThread().getStackTrace();

        // The call stack should look like:
        //   n [a variable number of calls depending on the vm used]
        //  +0 getCallOrigin()
        //  +1 privateLogFunction: verbose or debug
        //  +2 formatLogWithStack()
        //  +3 logFunction: v or d
        //  +4 caller

        int callerStackIndex;
        String logClassName = Log.class.getName();
        for (callerStackIndex = 0; callerStackIndex < st.length; callerStackIndex++) {
            if (st[callerStackIndex].getClassName().equals(logClassName)) {
                callerStackIndex += 4;
                break;
            }
        }

        return st[callerStackIndex].getFileName() + ":" + st[callerStackIndex].getLineNumber();
    }
}
