// Copyright 2015 The Vanadium 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 io.v.android.v23;

import java.io.BufferedReader;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import android.app.Application;
import android.util.Log;

/**
 * RedirectStderr redirects standard error to a file named stderr.log in the app's internal store.
 * On initialization, it will check for previously written stderr messages and output them to logcat
 * under the tag "VNativeLog".
 * When go panics, it outputs the panic message to stderr and RedirectStderr enables us to log these
 * panic messages to logcat.
 */
final class RedirectStderr {
    private static final String TAG = "RedirectStderr";
    /**
     * Start redirecting android's stderr
     */
    public static void Start() {
        dumpOldStderrLog();
        redirectStderr();
    }

    /**
     * Get the context of the currently running application. (Undocumented API).
     *
     * @return the application context
     */
    private static Application getApplication() {
        try {
            final Class<?> activityThreadClass = Class
                    .forName("android.app.ActivityThread");
            final Method method = activityThreadClass
                    .getMethod("currentApplication");
            final Application app = (Application) method.invoke(null,
                    (Object[]) null);
            if (app == null) {
                Log.e(TAG, "Application context was null");
            }
            return app;
        } catch (final Exception e) {
            Log.e(TAG, e.toString());
        }
        return null;
    }

    /**
     * Redirects stderr to the file specified by fileno.
     *
     * @param fileno the file descriptor number
     */
    private static native void nativeStart(int fileno);

    /**
     * Redirects stderr of the vanadium JNI code to a file. (Assumes a specific
     * implementation of FileDescriptor).
     */
    private static void redirectStderr() {
        Application app = getApplication();
        if (app == null) {
            return;
        }

        try {
            FileOutputStream fos = app.openFileOutput("stderr.log",
                    android.content.Context.MODE_PRIVATE);
            FileDescriptor fd = fos.getFD();
            Field fld = fd.getClass().getDeclaredField("descriptor");
            fld.setAccessible(true);
            int fileno = fld.getInt(fd);
            nativeStart(fileno);
        } catch (FileNotFoundException e) {
            Log.e("RedirectStderrGetFD", e.toString());
        } catch (IOException e) {
            Log.e("RedirectStderrOpenLog", e.toString());
            return;
        } catch (NoSuchFieldException e) {
            Log.e(TAG, "Failed to get descriptor field. It is highly likely that you are using a " +
                    "different version of java. Report this bug. " + e);
            return;
        } catch (IllegalAccessException e) {
            Log.e("RedirectStderrGetField", e.toString());
        } catch (IllegalArgumentException e) {
            Log.e("RedirectStderrGetField", e.toString());
        }
    }

    /**
     * Dumps the previously stored stderr log to the android logging system.
     */
    private static void dumpOldStderrLog() {
        Application app = getApplication();
        if (app == null) {
            return;
        }

        FileInputStream fis;
        try {
            fis = app.openFileInput("stderr.log");
        } catch (FileNotFoundException e) {
            return;
        }

        BufferedReader bf = new BufferedReader(new InputStreamReader(fis));
        while (true) {
            String line;
            try {
                line = bf.readLine();
            } catch (IOException e) {
                Log.e("DumpOldStderr", e.toString());
                break;
            }
            if (line == null) {
                break;
            }

            Log.i("VNativeLog", line);
        }

        try {
            bf.close();
        } catch (IOException e) {
        }

        app.deleteFile("stderr.log");
    }
}
