/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.systemui.classifier;

import android.app.ActivityThread;
import android.app.Application;
import android.os.Build;
import android.os.SystemProperties;
import android.util.Log;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayDeque;
import java.util.Date;
import java.util.Locale;

/**
 * Keeps track of interesting falsing data.
 *
 * By default the log only gets collected on userdebug builds. To turn it on on user:
 *  adb shell setprop debug.falsing_log true
 *
 * The log gets dumped as part of the SystemUI services. To dump on demand:
 *  adb shell dumpsys activity service com.android.systemui SystemBars | grep -A 999 FALSING | less
 *
 * To dump into logcat:
 *  adb shell setprop debug.falsing_logcat true
 *
 * To adjust the log buffer size:
 *  adb shell setprop debug.falsing_log_size 200
 */
public class FalsingLog {
    public static final boolean ENABLED = SystemProperties.getBoolean("debug.falsing_log",
            Build.IS_DEBUGGABLE);
    private static final boolean LOGCAT = SystemProperties.getBoolean("debug.falsing_logcat",
            false);

    public static final boolean VERBOSE = false;

    private static final int MAX_SIZE = SystemProperties.getInt("debug.falsing_log_size", 100);

    private static final String TAG = "FalsingLog";

    private final ArrayDeque<String> mLog = new ArrayDeque<>(MAX_SIZE);
    private final SimpleDateFormat mFormat = new SimpleDateFormat("MM-dd HH:mm:ss", Locale.US);

    private static FalsingLog sInstance;

    private FalsingLog() {
    }

    public static void v(String tag, String s) {
        if (!VERBOSE) {
            return;
        }
        if (LOGCAT) {
            Log.v(TAG, tag + "\t" + s);
        }
        log("V", tag, s);
    }

    public static void i(String tag, String s) {
        if (LOGCAT) {
            Log.i(TAG, tag + "\t" + s);
        }
        log("I", tag, s);
    }

    public static void w(String tag, String s) {
        if (LOGCAT) {
            Log.w(TAG, tag + "\t" + s);
        }
        log("W", tag, s);
    }

    public static void e(String tag, String s) {
        if (LOGCAT) {
            Log.e(TAG, tag + "\t" + s);
        }
        log("E", tag, s);
    }

    public static synchronized void log(String level, String tag, String s) {
        if (!ENABLED) {
            return;
        }
        if (sInstance == null) {
            sInstance = new FalsingLog();
        }

        if (sInstance.mLog.size() >= MAX_SIZE) {
            sInstance.mLog.removeFirst();
        }
        String entry = new StringBuilder().append(sInstance.mFormat.format(new Date()))
            .append(" ").append(level).append(" ")
            .append(tag).append(" ").append(s).toString();
        sInstance.mLog.add(entry);
    }

    public static synchronized void dump(PrintWriter pw) {
        pw.println("FALSING LOG:");
        if (!ENABLED) {
            pw.println("Disabled, to enable: setprop debug.falsing_log 1");
            pw.println();
            return;
        }
        if (sInstance == null || sInstance.mLog.isEmpty()) {
            pw.println("<empty>");
            pw.println();
            return;
        }
        for (String s : sInstance.mLog) {
            pw.println(s);
        }
        pw.println();
    }

    public static synchronized void wtf(String tag, String s) {
        if (!ENABLED) {
            return;
        }
        e(tag, s);

        Application application = ActivityThread.currentApplication();
        String fileMessage = "";
        if (Build.IS_DEBUGGABLE && application != null) {
            File f = new File(application.getDataDir(), "falsing-"
                    + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) + ".txt");
            PrintWriter pw = null;
            try {
                pw = new PrintWriter(f);
                dump(pw);
                pw.close();
                fileMessage = "Log written to " + f.getAbsolutePath();
            } catch (IOException e) {
                Log.e(TAG, "Unable to write falsing log", e);
            } finally {
                if (pw != null) {
                    pw.close();
                }
            }
        } else {
            Log.e(TAG, "Unable to write log, build must be debuggable.");
        }

        Log.wtf(TAG, tag + " " + s + "; " + fileMessage);
    }
}
