/*
 * Copyright (C) 2019 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 android.os;

import android.util.Log;

import java.io.BufferedInputStream;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;

/**
 * Helper for implementing {@link Binder#onShellCommand Binder.onShellCommand}. This is meant to
 * be copied into mainline modules, so this class must not use any hidden APIs.
 *
 * @hide
 */
public abstract class BasicShellCommandHandler {
    static final String TAG = "ShellCommand";
    static final boolean DEBUG = false;

    private Binder mTarget;
    private FileDescriptor mIn;
    private FileDescriptor mOut;
    private FileDescriptor mErr;
    private String[] mArgs;

    private String mCmd;
    private int mArgPos;
    private String mCurArgData;

    private FileInputStream mFileIn;
    private FileOutputStream mFileOut;
    private FileOutputStream mFileErr;

    private PrintWriter mOutPrintWriter;
    private PrintWriter mErrPrintWriter;
    private InputStream mInputStream;

    public void init(Binder target, FileDescriptor in, FileDescriptor out, FileDescriptor err,
            String[] args, int firstArgPos) {
        mTarget = target;
        mIn = in;
        mOut = out;
        mErr = err;
        mArgs = args;
        mCmd = null;
        mArgPos = firstArgPos;
        mCurArgData = null;
        mFileIn = null;
        mFileOut = null;
        mFileErr = null;
        mOutPrintWriter = null;
        mErrPrintWriter = null;
        mInputStream = null;
    }

    public int exec(Binder target, FileDescriptor in, FileDescriptor out, FileDescriptor err,
            String[] args) {
        String cmd;
        int start;
        if (args != null && args.length > 0) {
            cmd = args[0];
            start = 1;
        } else {
            cmd = null;
            start = 0;
        }
        init(target, in, out, err, args, start);
        mCmd = cmd;

        if (DEBUG) {
            RuntimeException here = new RuntimeException("here");
            here.fillInStackTrace();
            Log.d(TAG, "Starting command " + mCmd + " on " + mTarget, here);
            Log.d(TAG, "Calling uid=" + Binder.getCallingUid()
                    + " pid=" + Binder.getCallingPid());
        }
        int res = -1;
        try {
            res = onCommand(mCmd);
            if (DEBUG) Log.d(TAG, "Executed command " + mCmd + " on " + mTarget);
        } catch (Throwable e) {
            // Unlike usual calls, in this case if an exception gets thrown
            // back to us we want to print it back in to the dump data, since
            // that is where the caller expects all interesting information to
            // go.
            PrintWriter eout = getErrPrintWriter();
            eout.println();
            eout.println("Exception occurred while executing '" + mCmd + "':");
            e.printStackTrace(eout);
        } finally {
            if (DEBUG) Log.d(TAG, "Flushing output streams on " + mTarget);
            if (mOutPrintWriter != null) {
                mOutPrintWriter.flush();
            }
            if (mErrPrintWriter != null) {
                mErrPrintWriter.flush();
            }
            if (DEBUG) Log.d(TAG, "Sending command result on " + mTarget);
        }
        if (DEBUG) Log.d(TAG, "Finished command " + mCmd + " on " + mTarget);
        return res;
    }

    /**
     * Return the raw FileDescriptor for the output stream.
     */
    public FileDescriptor getOutFileDescriptor() {
        return mOut;
    }

    /**
     * Return direct raw access (not buffered) to the command's output data stream.
     */
    public OutputStream getRawOutputStream() {
        if (mFileOut == null) {
            mFileOut = new FileOutputStream(mOut);
        }
        return mFileOut;
    }

    /**
     * Return a PrintWriter for formatting output to {@link #getRawOutputStream()}.
     */
    public PrintWriter getOutPrintWriter() {
        if (mOutPrintWriter == null) {
            mOutPrintWriter = new PrintWriter(getRawOutputStream());
        }
        return mOutPrintWriter;
    }

    /**
     * Return the raw FileDescriptor for the error stream.
     */
    public FileDescriptor getErrFileDescriptor() {
        return mErr;
    }

    /**
     * Return direct raw access (not buffered) to the command's error output data stream.
     */
    public OutputStream getRawErrorStream() {
        if (mFileErr == null) {
            mFileErr = new FileOutputStream(mErr);
        }
        return mFileErr;
    }

    /**
     * Return a PrintWriter for formatting output to {@link #getRawErrorStream()}.
     */
    public PrintWriter getErrPrintWriter() {
        if (mErr == null) {
            return getOutPrintWriter();
        }
        if (mErrPrintWriter == null) {
            mErrPrintWriter = new PrintWriter(getRawErrorStream());
        }
        return mErrPrintWriter;
    }

    /**
     * Return the raw FileDescriptor for the input stream.
     */
    public FileDescriptor getInFileDescriptor() {
        return mIn;
    }

    /**
     * Return direct raw access (not buffered) to the command's input data stream.
     */
    public InputStream getRawInputStream() {
        if (mFileIn == null) {
            mFileIn = new FileInputStream(mIn);
        }
        return mFileIn;
    }

    /**
     * Return buffered access to the command's {@link #getRawInputStream()}.
     */
    public InputStream getBufferedInputStream() {
        if (mInputStream == null) {
            mInputStream = new BufferedInputStream(getRawInputStream());
        }
        return mInputStream;
    }

    /**
     * Return the next option on the command line -- that is an argument that
     * starts with '-'.  If the next argument is not an option, null is returned.
     */
    public String getNextOption() {
        if (mCurArgData != null) {
            String prev = mArgs[mArgPos - 1];
            throw new IllegalArgumentException("No argument expected after \"" + prev + "\"");
        }
        if (mArgPos >= mArgs.length) {
            return null;
        }
        String arg = mArgs[mArgPos];
        if (!arg.startsWith("-")) {
            return null;
        }
        mArgPos++;
        if (arg.equals("--")) {
            return null;
        }
        if (arg.length() > 1 && arg.charAt(1) != '-') {
            if (arg.length() > 2) {
                mCurArgData = arg.substring(2);
                return arg.substring(0, 2);
            } else {
                mCurArgData = null;
                return arg;
            }
        }
        mCurArgData = null;
        return arg;
    }

    /**
     * Return the next argument on the command line, whatever it is; if there are
     * no arguments left, return null.
     */
    public String getNextArg() {
        if (mCurArgData != null) {
            String arg = mCurArgData;
            mCurArgData = null;
            return arg;
        } else if (mArgPos < mArgs.length) {
            return mArgs[mArgPos++];
        } else {
            return null;
        }
    }

    public String peekNextArg() {
        if (mCurArgData != null) {
            return mCurArgData;
        } else if (mArgPos < mArgs.length) {
            return mArgs[mArgPos];
        } else {
            return null;
        }
    }

    /**
     * Returns number of arguments that haven't been processed yet.
     */
    public int getRemainingArgsCount() {
        if (mArgPos >= mArgs.length) {
            return 0;
        }
        return mArgs.length - mArgPos;
    }

    /**
     * Return the next argument on the command line, whatever it is; if there are
     * no arguments left, throws an IllegalArgumentException to report this to the user.
     */
    public String getNextArgRequired() {
        String arg = getNextArg();
        if (arg == null) {
            String prev = mArgs[mArgPos - 1];
            throw new IllegalArgumentException("Argument expected after \"" + prev + "\"");
        }
        return arg;
    }

    public int handleDefaultCommands(String cmd) {
        if (cmd == null || "help".equals(cmd) || "-h".equals(cmd)) {
            onHelp();
        } else {
            getOutPrintWriter().println("Unknown command: " + cmd);
        }
        return -1;
    }

    public Binder getTarget() {
        return mTarget;
    }

    public String[] getAllArgs() {
        return mArgs;
    }

    /**
     * Implement parsing and execution of a command.  If it isn't a command you understand,
     * call {@link #handleDefaultCommands(String)} and return its result as a last resort.
     * Use {@link #getNextOption()}, {@link #getNextArg()}, and {@link #getNextArgRequired()}
     * to process additional command line arguments.  Command output can be written to
     * {@link #getOutPrintWriter()} and errors to {@link #getErrPrintWriter()}.
     *
     * <p class="caution">Note that no permission checking has been done before entering this
     * function, so you need to be sure to do your own security verification for any commands you
     * are executing.  The easiest way to do this is to have the ShellCommand contain
     * only a reference to your service's aidl interface, and do all of your command
     * implementations on top of that -- that way you can rely entirely on your executing security
     * code behind that interface.</p>
     *
     * @param cmd The first command line argument representing the name of the command to execute.
     * @return Return the command result; generally 0 or positive indicates success and
     * negative values indicate error.
     */
    public abstract int onCommand(String cmd);

    /**
     * Implement this to print help text about your command to {@link #getOutPrintWriter()}.
     */
    public abstract void onHelp();
}
