// Copyright 2013 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.content.browser;

import android.content.Context;
import android.os.Handler;
import android.os.StrictMode;

import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
import org.chromium.base.ThreadUtils;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.library_loader.LibraryProcessType;
import org.chromium.base.library_loader.LoaderErrors;
import org.chromium.base.library_loader.ProcessInitException;
import org.chromium.content.app.ContentMain;
import org.chromium.content_public.browser.BrowserStartupController;
import org.chromium.content_public.browser.BrowserStartupController.StartupCallback;
import org.chromium.ui.resources.ResourceExtractor;

import java.util.ArrayList;
import java.util.List;

/**
 * Implementation of {@link BrowserStartupController}.
 * This is a singleton, and stores a reference to the application context.
 */
@JNINamespace("content")
public class BrowserStartupControllerImpl implements BrowserStartupController {
    private static final String TAG = "cr.BrowserStartup";

    // Helper constants for {@link #executeEnqueuedCallbacks(int, boolean)}.
    @VisibleForTesting
    static final int STARTUP_SUCCESS = -1;
    @VisibleForTesting
    static final int STARTUP_FAILURE = 1;

    private static BrowserStartupControllerImpl sInstance;

    private static boolean sShouldStartGpuProcessOnBrowserStartup;

    private static void setShouldStartGpuProcessOnBrowserStartup(boolean enable) {
        sShouldStartGpuProcessOnBrowserStartup = enable;
    }

    @VisibleForTesting
    @CalledByNative
    static void browserStartupComplete(int result) {
        if (sInstance != null) {
            sInstance.executeEnqueuedCallbacks(result);
        }
    }

    @CalledByNative
    static boolean shouldStartGpuProcessOnBrowserStartup() {
        return sShouldStartGpuProcessOnBrowserStartup;
    }

    // A list of callbacks that should be called when the async startup of the browser process is
    // complete.
    private final List<StartupCallback> mAsyncStartupCallbacks;

    // Whether the async startup of the browser process has started.
    private boolean mHasStartedInitializingBrowserProcess;

    // Whether tasks that occur after resource extraction have been completed.
    private boolean mPostResourceExtractionTasksCompleted;

    private boolean mHasCalledContentStart;

    // Whether the async startup of the browser process is complete.
    private boolean mStartupDone;

    // This field is set after startup has been completed based on whether the startup was a success
    // or not. It is used when later requests to startup come in that happen after the initial set
    // of enqueued callbacks have been executed.
    private boolean mStartupSuccess;

    private int mLibraryProcessType;

    private TracingControllerAndroid mTracingController;

    BrowserStartupControllerImpl(int libraryProcessType) {
        mAsyncStartupCallbacks = new ArrayList<>();
        mLibraryProcessType = libraryProcessType;
        ThreadUtils.postOnUiThread(new Runnable() {
            @Override
            public void run() {
                addStartupCompletedObserver(new StartupCallback() {
                    @Override
                    public void onSuccess() {
                        assert mTracingController == null;
                        Context context = ContextUtils.getApplicationContext();
                        mTracingController = new TracingControllerAndroid(context);
                        mTracingController.registerReceiver(context);
                    }

                    @Override
                    public void onFailure() {
                        // Startup failed.
                    }
                });
            }
        });
    }

    /**
     * Get BrowserStartupController instance, create a new one if no existing.
     *
     * @param libraryProcessType the type of process the shared library is loaded. it must be
     *                           LibraryProcessType.PROCESS_BROWSER or
     *                           LibraryProcessType.PROCESS_WEBVIEW.
     * @return BrowserStartupController instance.
     */
    public static BrowserStartupController get(int libraryProcessType) {
        assert ThreadUtils.runningOnUiThread() : "Tried to start the browser on the wrong thread.";
        ThreadUtils.assertOnUiThread();
        if (sInstance == null) {
            assert LibraryProcessType.PROCESS_BROWSER == libraryProcessType
                    || LibraryProcessType.PROCESS_WEBVIEW == libraryProcessType;
            sInstance = new BrowserStartupControllerImpl(libraryProcessType);
        }
        assert sInstance.mLibraryProcessType == libraryProcessType : "Wrong process type";
        return sInstance;
    }

    @VisibleForTesting
    public static void overrideInstanceForTest(BrowserStartupController controller) {
        sInstance = (BrowserStartupControllerImpl) controller;
    }

    @Override
    public void startBrowserProcessesAsync(boolean startGpuProcess, final StartupCallback callback)
            throws ProcessInitException {
        assert ThreadUtils.runningOnUiThread() : "Tried to start the browser on the wrong thread.";
        if (mStartupDone) {
            // Browser process initialization has already been completed, so we can immediately post
            // the callback.
            postStartupCompleted(callback);
            return;
        }

        // Browser process has not been fully started yet, so we defer executing the callback.
        mAsyncStartupCallbacks.add(callback);

        if (!mHasStartedInitializingBrowserProcess) {
            // This is the first time we have been asked to start the browser process. We set the
            // flag that indicates that we have kicked off starting the browser process.
            mHasStartedInitializingBrowserProcess = true;

            setShouldStartGpuProcessOnBrowserStartup(startGpuProcess);
            prepareToStartBrowserProcess(false, new Runnable() {
                @Override
                public void run() {
                    ThreadUtils.assertOnUiThread();
                    if (mHasCalledContentStart) return;
                    if (contentStart() > 0) {
                        // Failed. The callbacks may not have run, so run them.
                        enqueueCallbackExecution(STARTUP_FAILURE);
                    }
                }
            });
        }
    }

    @Override
    public void startBrowserProcessesSync(boolean singleProcess) throws ProcessInitException {
        // If already started skip to checking the result
        if (!mStartupDone) {
            if (!mHasStartedInitializingBrowserProcess || !mPostResourceExtractionTasksCompleted) {
                prepareToStartBrowserProcess(singleProcess, null);
            }

            boolean startedSuccessfully = true;
            if (!mHasCalledContentStart) {
                if (contentStart() > 0) {
                    // Failed. The callbacks may not have run, so run them.
                    enqueueCallbackExecution(STARTUP_FAILURE);
                    startedSuccessfully = false;
                }
            }
            if (startedSuccessfully) {
                flushStartupTasks();
            }
        }

        // Startup should now be complete
        assert mStartupDone;
        if (!mStartupSuccess) {
            throw new ProcessInitException(LoaderErrors.LOADER_ERROR_NATIVE_STARTUP_FAILED);
        }
    }

    /**
     * Wrap ContentMain.start() for testing.
     */
    @VisibleForTesting
    int contentStart() {
        assert !mHasCalledContentStart;
        mHasCalledContentStart = true;
        return ContentMain.start();
    }

    @VisibleForTesting
    void flushStartupTasks() {
        nativeFlushStartupTasks();
    }

    @Override
    public boolean isStartupSuccessfullyCompleted() {
        ThreadUtils.assertOnUiThread();
        return mStartupDone && mStartupSuccess;
    }

    @Override
    public void addStartupCompletedObserver(StartupCallback callback) {
        ThreadUtils.assertOnUiThread();
        if (mStartupDone) {
            postStartupCompleted(callback);
        } else {
            mAsyncStartupCallbacks.add(callback);
        }
    }

    private void executeEnqueuedCallbacks(int startupResult) {
        assert ThreadUtils.runningOnUiThread() : "Callback from browser startup from wrong thread.";
        mStartupDone = true;
        mStartupSuccess = (startupResult <= 0);
        for (StartupCallback asyncStartupCallback : mAsyncStartupCallbacks) {
            if (mStartupSuccess) {
                asyncStartupCallback.onSuccess();
            } else {
                asyncStartupCallback.onFailure();
            }
        }
        // We don't want to hold on to any objects after we do not need them anymore.
        mAsyncStartupCallbacks.clear();
    }

    // Queue the callbacks to run. Since running the callbacks clears the list it is safe to call
    // this more than once.
    private void enqueueCallbackExecution(final int startupFailure) {
        new Handler().post(new Runnable() {
            @Override
            public void run() {
                executeEnqueuedCallbacks(startupFailure);
            }
        });
    }

    private void postStartupCompleted(final StartupCallback callback) {
        new Handler().post(new Runnable() {
            @Override
            public void run() {
                if (mStartupSuccess) {
                    callback.onSuccess();
                } else {
                    callback.onFailure();
                }
            }
        });
    }

    @VisibleForTesting
    void prepareToStartBrowserProcess(final boolean singleProcess,
            final Runnable completionCallback) throws ProcessInitException {
        Log.i(TAG, "Initializing chromium process, singleProcess=%b", singleProcess);

        // This strictmode exception is to cover the case where the browser process is being started
        // asynchronously but not in the main browser flow.  The main browser flow will trigger
        // library loading earlier and this will be a no-op, but in the other cases this will need
        // to block on loading libraries.
        // This applies to tests and ManageSpaceActivity, which can be launched from Settings.
        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
        try {
            // Normally Main.java will have already loaded the library asynchronously, we only need
            // to load it here if we arrived via another flow, e.g. bookmark access & sync setup.
            LibraryLoader.getInstance().ensureInitialized(mLibraryProcessType);
        } finally {
            StrictMode.setThreadPolicy(oldPolicy);
        }

        Runnable postResourceExtraction = new Runnable() {
            @Override
            public void run() {
                if (!mPostResourceExtractionTasksCompleted) {
                    // TODO(yfriedman): Remove dependency on a command line flag for this.
                    DeviceUtilsImpl.addDeviceSpecificUserAgentSwitch(
                            ContextUtils.getApplicationContext());
                    nativeSetCommandLineFlags(
                            singleProcess, nativeIsPluginEnabled() ? getPlugins() : null);
                    mPostResourceExtractionTasksCompleted = true;
                }

                if (completionCallback != null) completionCallback.run();
            }
        };

        if (completionCallback == null) {
            // If no continuation callback is specified, then force the resource extraction
            // to complete.
            ResourceExtractor.get().waitForCompletion();
            postResourceExtraction.run();
        } else {
            ResourceExtractor.get().addCompletionCallback(postResourceExtraction);
        }
    }

    /**
     * Initialization needed for tests. Mainly used by content browsertests.
     */
    @Override
    public void initChromiumBrowserProcessForTests() {
        ResourceExtractor resourceExtractor = ResourceExtractor.get();
        resourceExtractor.startExtractingResources();
        resourceExtractor.waitForCompletion();
        nativeSetCommandLineFlags(false, null);
    }

    private String getPlugins() {
        return PepperPluginManager.getPlugins(ContextUtils.getApplicationContext());
    }

    private static native void nativeSetCommandLineFlags(
            boolean singleProcess, String pluginDescriptor);

    // Is this an official build of Chrome? Only native code knows for sure. Official build
    // knowledge is needed very early in process startup.
    private static native boolean nativeIsOfficialBuild();

    private static native boolean nativeIsPluginEnabled();

    private static native void nativeFlushStartupTasks();
}
