// Copyright 2017 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.process_launcher;

import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;

import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
import org.chromium.base.TraceEvent;

import java.io.IOException;
import java.util.List;

/**
 * This class is used to start a child process by connecting to a ChildProcessService.
 */
public class ChildProcessLauncher {
    private static final String TAG = "ChildProcLauncher";

    /** Delegate that client should use to customize the process launching. */
    public abstract static class Delegate {
        /**
         * Called when the launcher is about to start. Gives the embedder a chance to provide an
         * already bound connection if it has one. (allowing for warm-up connections: connections
         * that are already bound in advance to speed up child process start-up time).
         * Note that onBeforeConnectionAllocated will not be called if this method returns a
         * connection.
         * @param connectionAllocator the allocator the returned connection should have been
         * allocated of.
         * @param serviceCallback the service callback that the connection should use.
         * @return a bound connection to use to connect to the child process service, or null if a
         * connection should be allocated and bound by the launcher.
         */
        public ChildProcessConnection getBoundConnection(
                ChildConnectionAllocator connectionAllocator,
                ChildProcessConnection.ServiceCallback serviceCallback) {
            return null;
        }

        /**
         * Called before a connection is allocated.
         * Note that this is only called if the ChildProcessLauncher is created with
         * {@link #createWithConnectionAllocator}.
         * @param serviceBundle the bundle passed in the service intent. Clients can add their own
         * extras to the bundle.
         */
        public void onBeforeConnectionAllocated(Bundle serviceBundle) {}

        /**
         * Called before setup is called on the connection.
         * @param connectionBundle the bundle passed to the {@link ChildProcessService} in the
         * setup call. Clients can add their own extras to the bundle.
         */
        public void onBeforeConnectionSetup(Bundle connectionBundle) {}

        /**
         * Called when the connection was successfully established, meaning the setup call on the
         * service was successful.
         * @param connection the connection over which the setup call was made.
         */
        public void onConnectionEstablished(ChildProcessConnection connection) {}

        /**
         * Called when a connection has been disconnected. Only invoked if onConnectionEstablished
         * was called, meaning the connection was already established.
         * @param connection the connection that got disconnected.
         */
        public void onConnectionLost(ChildProcessConnection connection) {}
    }

    // Represents an invalid process handle; same as base/process/process.h kNullProcessHandle.
    private static final int NULL_PROCESS_HANDLE = 0;

    // The handle for the thread we were created on and on which all methods should be called.
    private final Handler mLauncherHandler;

    private final Delegate mDelegate;

    private final String[] mCommandLine;
    private final FileDescriptorInfo[] mFilesToBeMapped;

    // The allocator used to create the connection.
    private final ChildConnectionAllocator mConnectionAllocator;

    // The IBinder interfaces provided to the created service.
    private final List<IBinder> mClientInterfaces;

    // The actual service connection. Set once we have connected to the service.
    private ChildProcessConnection mConnection;

    /**
     * Constructor.
     *
     * @param launcherHandler the handler for the thread where all operations should happen.
     * @param delegate the delagate that gets notified of the launch progress.
     * @param commandLine the command line that should be passed to the started process.
     * @param filesToBeMapped the files that should be passed to the started process.
     * @param connectionAllocator the allocator used to create connections to the service.
     * @param clientInterfaces the interfaces that should be passed to the started process so it can
     * communicate with the parent process.
     */
    public ChildProcessLauncher(Handler launcherHandler, Delegate delegate, String[] commandLine,
            FileDescriptorInfo[] filesToBeMapped, ChildConnectionAllocator connectionAllocator,
            List<IBinder> clientInterfaces) {
        assert connectionAllocator != null;
        mLauncherHandler = launcherHandler;
        isRunningOnLauncherThread();
        mCommandLine = commandLine;
        mConnectionAllocator = connectionAllocator;
        mDelegate = delegate;
        mFilesToBeMapped = filesToBeMapped;
        mClientInterfaces = clientInterfaces;
    }

    /**
     * Starts the child process and calls setup on it if {@param setupConnection} is true.
     * @param setupConnection whether the setup should be performed on the connection once
     * established
     * @param queueIfNoFreeConnection whether to queue that request if no service connection is
     * available. If the launcher was created with a connection provider, this parameter has no
     * effect.
     * @return true if the connection was started or was queued.
     */
    public boolean start(final boolean setupConnection, final boolean queueIfNoFreeConnection) {
        assert isRunningOnLauncherThread();
        try {
            TraceEvent.begin("ChildProcessLauncher.start");
            ChildProcessConnection.ServiceCallback serviceCallback =
                    new ChildProcessConnection.ServiceCallback() {
                        @Override
                        public void onChildStarted() {}

                        @Override
                        public void onChildStartFailed(ChildProcessConnection connection) {
                            assert isRunningOnLauncherThread();
                            assert mConnection == connection;
                            Log.e(TAG, "ChildProcessConnection.start failed, trying again");
                            mLauncherHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    // The child process may already be bound to another client
                                    // (this can happen if multi-process WebView is used in more
                                    // than one process), so try starting the process again.
                                    // This connection that failed to start has not been freed,
                                    // so a new bound connection will be allocated.
                                    mConnection = null;
                                    start(setupConnection, queueIfNoFreeConnection);
                                }
                            });
                        }

                        @Override
                        public void onChildProcessDied(ChildProcessConnection connection) {
                            assert isRunningOnLauncherThread();
                            assert mConnection == connection;
                            ChildProcessLauncher.this.onChildProcessDied();
                        }
                    };
            mConnection = mDelegate.getBoundConnection(mConnectionAllocator, serviceCallback);
            if (mConnection != null) {
                assert mConnectionAllocator.isConnectionFromAllocator(mConnection);
                setupConnection();
                return true;
            }
            if (!allocateAndSetupConnection(
                        serviceCallback, setupConnection, queueIfNoFreeConnection)
                    && !queueIfNoFreeConnection) {
                return false;
            }
            return true;
        } finally {
            TraceEvent.end("ChildProcessLauncher.start");
        }
    }

    public ChildProcessConnection getConnection() {
        return mConnection;
    }

    public ChildConnectionAllocator getConnectionAllocator() {
        return mConnectionAllocator;
    }

    private boolean allocateAndSetupConnection(
            final ChildProcessConnection.ServiceCallback serviceCallback,
            final boolean setupConnection, final boolean queueIfNoFreeConnection) {
        assert mConnection == null;
        Bundle serviceBundle = new Bundle();
        mDelegate.onBeforeConnectionAllocated(serviceBundle);

        mConnection = mConnectionAllocator.allocate(
                ContextUtils.getApplicationContext(), serviceBundle, serviceCallback);
        if (mConnection == null) {
            if (!queueIfNoFreeConnection) {
                Log.d(TAG, "Failed to allocate a child connection (no queuing).");
                return false;
            }
            mConnectionAllocator.queueAllocation(
                    () -> allocateAndSetupConnection(
                                    serviceCallback, setupConnection, queueIfNoFreeConnection));
            return false;
        }

        if (setupConnection) {
            setupConnection();
        }
        return true;
    }

    private void setupConnection() {
        ChildProcessConnection.ConnectionCallback connectionCallback =
                new ChildProcessConnection.ConnectionCallback() {
                    @Override
                    public void onConnected(ChildProcessConnection connection) {
                        onServiceConnected(connection);
                    }
                };
        Bundle connectionBundle = createConnectionBundle();
        mDelegate.onBeforeConnectionSetup(connectionBundle);
        mConnection.setupConnection(connectionBundle, getClientInterfaces(), connectionCallback);
    }

    private void onServiceConnected(ChildProcessConnection connection) {
        assert isRunningOnLauncherThread();
        assert mConnection == connection || connection == null;

        Log.d(TAG, "on connect callback, pid=%d", mConnection.getPid());

        mDelegate.onConnectionEstablished(mConnection);

        // Proactively close the FDs rather than waiting for the GC to do it.
        try {
            for (FileDescriptorInfo fileInfo : mFilesToBeMapped) {
                fileInfo.fd.close();
            }
        } catch (IOException ioe) {
            Log.w(TAG, "Failed to close FD.", ioe);
        }
    }

    public int getPid() {
        assert isRunningOnLauncherThread();
        return mConnection == null ? NULL_PROCESS_HANDLE : mConnection.getPid();
    }

    public List<IBinder> getClientInterfaces() {
        return mClientInterfaces;
    }

    private boolean isRunningOnLauncherThread() {
        return mLauncherHandler.getLooper() == Looper.myLooper();
    }

    private Bundle createConnectionBundle() {
        Bundle bundle = new Bundle();
        bundle.putStringArray(ChildProcessConstants.EXTRA_COMMAND_LINE, mCommandLine);
        bundle.putParcelableArray(ChildProcessConstants.EXTRA_FILES, mFilesToBeMapped);
        return bundle;
    }

    private void onChildProcessDied() {
        assert isRunningOnLauncherThread();
        if (getPid() != 0) {
            mDelegate.onConnectionLost(mConnection);
        }
    }

    public void stop() {
        assert isRunningOnLauncherThread();
        Log.d(TAG, "stopping child connection: pid=%d", mConnection.getPid());
        mConnection.stop();
    }
}
