/*
 * Copyright (C) 2012 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.utils;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.google.common.io.Closeables;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class GrabProcessOutput {

    public enum Wait {
        /**
         * Doesn't wait for the exec to complete.
         * This still monitors the output but does not wait for the process to finish.
         * In this mode the process return code is unknown and always 0.
         */
        ASYNC,
        /**
         * This waits for the process to finish.
         * In this mode, {@link GrabProcessOutput#grabProcessOutput} returns the
         * error code from the process.
         * In some rare cases and depending on the OS, the process might not have
         * finished dumping data into stdout/stderr.
         * <p/>
         * Use this when you don't particularly care for the output but instead
         * care for the return code of the executed process.
         */
        WAIT_FOR_PROCESS,
        /**
         * This waits for the process to finish <em>and</em> for the stdout/stderr
         * threads to complete.
         * In this mode, {@link GrabProcessOutput#grabProcessOutput} returns the
         * error code from the process.
         * <p/>
         * Use this one when capturing all the output from the process is important.
         */
        WAIT_FOR_READERS,
    }

    public interface IProcessOutput {
        /**
         * Processes an stdout message line.
         * @param line The stdout message line. Null when the reader reached the end of stdout.
         */
        void out(@Nullable String line);
        /**
         * Processes an stderr message line.
         * @param line The stderr message line. Null when the reader reached the end of stderr.
         */
        void err(@Nullable String line);
    }

    /**
     * Get the stderr/stdout outputs of a process and return when the process is done.
     * Both <b>must</b> be read or the process will block on windows.
     *
     * @param process The process to get the output from.
     * @param output Optional object to capture stdout/stderr.
     *      Note that on Windows capturing the output is not optional. If output is null
     *      the stdout/stderr will be captured and discarded.
     * @param waitMode Whether to wait for the process and/or the readers to finish.
     * @return the process return code.
     * @throws InterruptedException if {@link Process#waitFor()} was interrupted.
     */
    public static int grabProcessOutput(
            @NonNull final Process process,
            Wait waitMode,
            @Nullable final IProcessOutput output) throws InterruptedException {
        // read the lines as they come. if null is returned, it's
        // because the process finished
        Thread threadErr = new Thread("stderr") {
            @Override
            public void run() {
                // create a buffer to read the stderr output
                InputStream is = process.getErrorStream();
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader errReader = new BufferedReader(isr);

                try {
                    while (true) {
                        String line = errReader.readLine();
                        if (output != null) {
                            output.err(line);
                        }
                        if (line == null) {
                            break;
                        }
                    }
                } catch (IOException e) {
                    // do nothing.
                } finally {
                    try {
                        Closeables.close(is, true /* swallowIOException */);
                    } catch (IOException e) {
                        // cannot happen
                    }
                    try {
                        Closeables.close(isr, true /* swallowIOException */);
                    } catch (IOException e) {
                        // cannot happen
                    }
                    try {
                        Closeables.close(errReader, true /* swallowIOException */);
                    } catch (IOException e) {
                        // cannot happen
                    }
                }
            }
        };

        Thread threadOut = new Thread("stdout") {
            @Override
            public void run() {
                InputStream is = process.getInputStream();
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader outReader = new BufferedReader(isr);

                try {
                    while (true) {
                        String line = outReader.readLine();
                        if (output != null) {
                            output.out(line);
                        }
                        if (line == null) {
                            break;
                        }
                    }
                } catch (IOException e) {
                    // do nothing.
                } finally {
                    try {
                        Closeables.close(is, true /* swallowIOException */);
                    } catch (IOException e) {
                        // cannot happen
                    }
                    try {
                        Closeables.close(isr, true /* swallowIOException */);
                    } catch (IOException e) {
                        // cannot happen
                    }
                    try {
                        Closeables.close(outReader, true /* swallowIOException */);
                    } catch (IOException e) {
                        // cannot happen
                    }
                }
            }
        };

        threadErr.start();
        threadOut.start();

        if (waitMode == Wait.ASYNC) {
            return 0;
        }

        // it looks like on windows process#waitFor() can return
        // before the thread have filled the arrays, so we wait for both threads and the
        // process itself.
        if (waitMode == Wait.WAIT_FOR_READERS) {
            try {
                threadErr.join();
            } catch (InterruptedException e) {
            }
            try {
                threadOut.join();
            } catch (InterruptedException e) {
            }
        }

        // get the return code from the process
        return process.waitFor();
    }
}
