/*
 * Copyright (C) 2017 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.tools.ir.server;

import static android.app.ActivityManager.ProcessErrorStateInfo.NO_ERROR;
import static com.android.tools.ir.server.Logging.LOG_TAG;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.os.Build;
import android.util.ArrayMap;
import android.util.Log;
import android.widget.Toast;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Handler capable of restarting parts of the application in order for changes to become apparent to
 * the user:
 *
 * <ul>
 *   <li>Apply a tiny change immediately - possible if we can detect that the change is only used in
 *       a limited context (such as in a layout) and we can directly poke the view hierarchy and
 *       schedule a paint.
 *   <li>Apply a change to the current activity. We can restart just the activity while the app
 *       continues running.
 *   <li>Restart the app with state persistence (simulates what happens when a user puts an app in
 *       the background, then it gets killed by the memory monitor, and then restored when the user
 *       brings it back
 *   <li>Restart the app completely.
 * </ul>
 */
public class Restarter {
    /** Restart an activity. Should preserve as much state as possible. */
    public static void restartActivityOnUiThread(@NonNull final Activity activity) {
        activity.runOnUiThread(
                new Runnable() {
                    @Override
                    public void run() {
                        if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) {
                            Log.v(LOG_TAG, "Resources updated: notify activities");
                        }
                        updateActivity(activity);
                    }
                });
    }

    private static void restartActivity(@NonNull Activity activity) {
        if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) {
            Log.v(LOG_TAG, "About to restart " + activity.getClass().getSimpleName());
        }

        // You can't restart activities that have parents: find the top-most activity
        while (activity.getParent() != null) {
            if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) {
                Log.v(
                        LOG_TAG,
                        activity.getClass().getSimpleName()
                                + " is not a top level activity; restarting "
                                + activity.getParent().getClass().getSimpleName()
                                + " instead");
            }
            activity = activity.getParent();
        }

        // Directly supported by the framework!
        activity.recreate();
    }

    /**
     * Attempt to restart the app. Ideally this should also try to preserve as much state as
     * possible:
     * <ul>
     *     <li>The current activity</li>
     *     <li>If possible, state in the current activity, and</li>
     *     <li>The activity stack</li>
     * </ul>
     *
     * This may require some framework support. Apparently it may already be possible
     * (Dianne says to put the app in the background, kill it then restart it; need to
     * figure out how to do this.)
     */
    public static void restartApp(@Nullable Context appContext,
                                  @NonNull Collection<Activity> knownActivities,
                                  boolean toast) {
        if (!knownActivities.isEmpty()) {
            // Can't live patch resources; instead, try to restart the current activity
            Activity foreground = getForegroundActivity(appContext);

            if (foreground != null) {
                // http://stackoverflow.com/questions/6609414/howto-programatically-restart-android-app
                //noinspection UnnecessaryLocalVariable
                if (toast) {
                    showToast(foreground, "Restarting app to apply incompatible changes");
                }
                if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) {
                    Log.v(LOG_TAG, "RESTARTING APP");
                }
                @SuppressWarnings("UnnecessaryLocalVariable") // fore code clarify
                Context context = foreground;
                Intent intent = new Intent(context, foreground.getClass());
                int intentId = 0;
                PendingIntent pendingIntent = PendingIntent.getActivity(context, intentId,
                        intent, PendingIntent.FLAG_CANCEL_CURRENT);
                AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
                mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, pendingIntent);
                if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) {
                    Log.v(
                            LOG_TAG,
                            "Scheduling activity "
                                    + foreground
                                    + " to start after exiting process");
                }
            } else {
                showToast(knownActivities.iterator().next(), "Unable to restart app");
                if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) {
                    Log.v(
                            LOG_TAG,
                            "Couldn't find any foreground activities to restart "
                                    + "for resource refresh");
                }
            }
            System.exit(0);
        }
    }

    static void showToast(@NonNull final Activity activity, @NonNull final String text) {
        if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) {
            Log.v(LOG_TAG, "About to show toast for activity " + activity + ": " + text);
        }
        activity.runOnUiThread(
                new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Context context = activity.getApplicationContext();
                            if (context instanceof ContextWrapper) {
                                Context base = ((ContextWrapper) context).getBaseContext();
                                if (base == null) {
                                    if (Log.isLoggable(LOG_TAG, Log.WARN)) {
                                        Log.w(LOG_TAG, "Couldn't show toast: no base context");
                                    }
                                    return;
                                }
                            }

                            // For longer messages, leave the message up longer
                            int duration = Toast.LENGTH_SHORT;
                            if (text.length() >= 60 || text.indexOf('\n') != -1) {
                                duration = Toast.LENGTH_LONG;
                            }

                            // Avoid crashing when not available, e.g.
                            //   java.lang.RuntimeException: Can't create handler inside thread that has
                            //        not called Looper.prepare()
                            Toast.makeText(activity, text, duration).show();
                        } catch (Throwable e) {
                            if (Log.isLoggable(LOG_TAG, Log.WARN)) {
                                Log.w(LOG_TAG, "Couldn't show toast", e);
                            }
                        }
                    }
                });
    }

    @Nullable
    public static Activity getForegroundActivity(@Nullable Context context) {
        List<Activity> list = getActivities(context, true);
        return list.isEmpty() ? null : list.get(0);
    }

    // http://stackoverflow.com/questions/11411395/how-to-get-current-foreground-activity-context-in-android
    @NonNull
    public static List<Activity> getActivities(@Nullable Context context, boolean foregroundOnly) {
        List<Activity> list = new ArrayList<Activity>();
        try {
            Class activityThreadClass = Class.forName("android.app.ActivityThread");
            Object activityThread = MonkeyPatcher.getActivityThread(context, activityThreadClass);
            Field activitiesField = activityThreadClass.getDeclaredField("mActivities");
            activitiesField.setAccessible(true);

            // check app hasn't crashed, if it has, return empty list of activities.
            if (hasAppCrashed(context, activityThreadClass, activityThread)) {
                return new ArrayList<Activity>();
            }

            Collection c;
            Object collection = activitiesField.get(activityThread);

            if (collection instanceof HashMap) {
                // Older platforms
                Map activities = (HashMap) collection;
                c = activities.values();
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT &&
                    collection instanceof ArrayMap) {
                ArrayMap activities = (ArrayMap) collection;
                c = activities.values();
            } else {
                return list;
            }

            for (Object activityClientRecord : c) {
                Class activityClientRecordClass = activityClientRecord.getClass();
                if (foregroundOnly) {
                    Field pausedField = activityClientRecordClass.getDeclaredField("paused");
                    pausedField.setAccessible(true);
                    if (pausedField.getBoolean(activityClientRecord)) {
                        continue;
                    }
                }
                Field activityField = activityClientRecordClass.getDeclaredField("activity");
                activityField.setAccessible(true);
                Activity activity = (Activity) activityField.get(activityClientRecord);
                if (activity != null) {
                    list.add(activity);
                }
            }
        } catch (Throwable e) {
            if (Log.isLoggable(LOG_TAG, Log.WARN)) {
                Log.w(LOG_TAG, "Error retrieving activities", e);
            }
        }
        return list;
    }

    /**
     * Checks if the application has crashed by comparing the package name against the list of
     * processes in error state.
     */
    private static boolean hasAppCrashed(
            @Nullable Context context,
            @NonNull Class activityThreadClass,
            @Nullable Object activityThread)
            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        if (context == null || activityThread == null) {
            return false;
        }

        String currentPackageName = getPackageName(activityThreadClass, activityThread);

        ActivityManager manager =
                (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.ProcessErrorStateInfo> processesInErrorState =
                manager.getProcessesInErrorState();
        if (processesInErrorState != null) { // returns null if no process in error state
            for (ActivityManager.ProcessErrorStateInfo info : processesInErrorState) {
                if (info.processName.equals(currentPackageName) && info.condition != NO_ERROR) {
                    if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) {
                        Log.v(LOG_TAG, "App Thread has crashed, return empty activity list.");
                    }
                    return true;
                }
            }
        }
        return false;
    }

    // Use reflection to determine the package name from activity thread.
    private static String getPackageName(
            @NonNull Class activityThreadClass, @Nullable Object activityThread)
            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        Method currentPackageNameMethod =
                activityThreadClass.getDeclaredMethod("currentPackageName");
        return (String) currentPackageNameMethod.invoke(activityThread);
    }

    private static void updateActivity(@NonNull Activity activity) {
        // This method can be called for activities that are not in the foreground, as long
        // as some of its resources have been updated. Therefore we'll need to make sure
        // that this activity is in the foreground, and if not do nothing. Ways to do
        // that are outlined here:
        // http://stackoverflow.com/questions/3667022/checking-if-an-android-application-is-running-in-the-background/5862048#5862048

        // Try to force re-layout; there are many approaches; see
        // http://stackoverflow.com/questions/5991968/how-to-force-an-entire-layout-view-refresh

        // This doesn't seem to update themes properly -- may need to do recreate() instead!
        //getWindow().getDecorView().findViewById(android.R.id.content).invalidate();

        // This is a bit of a sledgehammer. We should consider having an incremental updater,
        // similar to IntelliJ's Look &amp; Feel updater which iterates to the view hierarchy
        // and tries to incrementally refresh the LAF delegates and force a repaint.
        // On the other hand, we may never be able to succeed with that, since there could be
        // UI elements on the screen cached from callbacks. I should probably *not* attempt
        // to try to poke the user's data models; recreating the current layout should be
        // enough (e.g. if a layout references @string/foo, we'll recreate those widgets
        //    if (mLastContentView != -1) {
        //        setContentView(mLastContentView);
        //    } else {
        //        recreate();
        //    }
        // -- nope, even that's iffy. I had code which *after* calling setContentView would
        // do some findViewById calls etc to reinitialize views.
        //
        // So what I should really try to do is have some knowledge about what changed,
        // and see if I can figure out that the change is minor (e.g. doesn't affect themes
        // or layout parameters etc), and if so, just try to poke the view hierarchy directly,
        // and if not, just recreate

        //    if (changeManager.isSimpleDelta()) {
        //        changeManager.applyDirectly(this);
        //    } else {

        // Note: This doesn't handle manifest changes like changing the application title

        restartActivity(activity);
    }
}
