/*
** Copyright 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.commands.content;

import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.app.IActivityManager.ContentProviderHolder;
import android.content.ContentValues;
import android.content.IContentProvider;
import android.database.Cursor;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.UserHandle;
import android.text.TextUtils;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import libcore.io.IoUtils;

/**
 * This class is a command line utility for manipulating content. A client
 * can insert, update, and remove records in a content provider. For example,
 * some settings may be configured before running the CTS tests, etc.
 * <p>
 * Examples:
 * <ul>
 * <li>
 * # Add "new_setting" secure setting with value "new_value".</br>
 * adb shell content insert --uri content://settings/secure --bind name:s:new_setting
 *  --bind value:s:new_value
 * </li>
 * <li>
 * # Change "new_setting" secure setting to "newer_value" (You have to escape single quotes in
 * the where clause).</br>
 * adb shell content update --uri content://settings/secure --bind value:s:newer_value
 *  --where "name=\'new_setting\'"
 * </li>
 * <li>
 * # Remove "new_setting" secure setting.</br>
 * adb shell content delete --uri content://settings/secure --where "name=\'new_setting\'"
 * </li>
 * <li>
 * # Query \"name\" and \"value\" columns from secure settings where \"name\" is equal to"
 *    \"new_setting\" and sort the result by name in ascending order.\n"
 * adb shell content query --uri content://settings/secure --projection name:value
 *  --where "name=\'new_setting\'" --sort \"name ASC\"
 * </li>
 * </ul>
 * </p>
 */
public class Content {

    private static final String USAGE =
        "usage: adb shell content [subcommand] [options]\n"
        + "\n"
        + "usage: adb shell content insert --uri <URI> [--user <USER_ID>]"
                + " --bind <BINDING> [--bind <BINDING>...]\n"
        + "  <URI> a content provider URI.\n"
        + "  <BINDING> binds a typed value to a column and is formatted:\n"
        + "  <COLUMN_NAME>:<TYPE>:<COLUMN_VALUE> where:\n"
        + "  <TYPE> specifies data type such as:\n"
        + "  b - boolean, s - string, i - integer, l - long, f - float, d - double\n"
        + "  Note: Omit the value for passing an empty string, e.g column:s:\n"
        + "  Example:\n"
        + "  # Add \"new_setting\" secure setting with value \"new_value\".\n"
        + "  adb shell content insert --uri content://settings/secure --bind name:s:new_setting"
                + " --bind value:s:new_value\n"
        + "\n"
        + "usage: adb shell content update --uri <URI> [--user <USER_ID>] [--where <WHERE>]\n"
        + "  <WHERE> is a SQL style where clause in quotes (You have to escape single quotes"
                + " - see example below).\n"
        + "  Example:\n"
        + "  # Change \"new_setting\" secure setting to \"newer_value\".\n"
        + "  adb shell content update --uri content://settings/secure --bind"
                + " value:s:newer_value --where \"name=\'new_setting\'\"\n"
        + "\n"
        + "usage: adb shell content delete --uri <URI> [--user <USER_ID>] --bind <BINDING>"
                + " [--bind <BINDING>...] [--where <WHERE>]\n"
        + "  Example:\n"
        + "  # Remove \"new_setting\" secure setting.\n"
        + "  adb shell content delete --uri content://settings/secure "
                + "--where \"name=\'new_setting\'\"\n"
        + "\n"
        + "usage: adb shell content query --uri <URI> [--user <USER_ID>]"
                + " [--projection <PROJECTION>] [--where <WHERE>] [--sort <SORT_ORDER>]\n"
        + "  <PROJECTION> is a list of colon separated column names and is formatted:\n"
        + "  <COLUMN_NAME>[:<COLUMN_NAME>...]\n"
        + "  <SORT_ORDER> is the order in which rows in the result should be sorted.\n"
        + "  Example:\n"
        + "  # Select \"name\" and \"value\" columns from secure settings where \"name\" is "
                + "equal to \"new_setting\" and sort the result by name in ascending order.\n"
        + "  adb shell content query --uri content://settings/secure --projection name:value"
                + " --where \"name=\'new_setting\'\" --sort \"name ASC\"\n"
        + "\n"
        + "usage: adb shell content call --uri <URI> --method <METHOD> [--arg <ARG>]\n"
        + "       [--extra <BINDING> ...]\n"
        + "  <METHOD> is the name of a provider-defined method\n"
        + "  <ARG> is an optional string argument\n"
        + "  <BINDING> is like --bind above, typed data of the form <KEY>:{b,s,i,l,f,d}:<VAL>\n"
        + "\n"
        + "usage: adb shell content read --uri <URI> [--user <USER_ID>]\n"
        + "  Example:\n"
        + "  # cat default ringtone to a file, then pull to host\n"
        + "  adb shell 'content read --uri content://settings/system/ringtone >"
                + " /mnt/sdcard/tmp.ogg' && adb pull /mnt/sdcard/tmp.ogg\n"
        + "\n";

    private static class Parser {
        private static final String ARGUMENT_INSERT = "insert";
        private static final String ARGUMENT_DELETE = "delete";
        private static final String ARGUMENT_UPDATE = "update";
        private static final String ARGUMENT_QUERY = "query";
        private static final String ARGUMENT_CALL = "call";
        private static final String ARGUMENT_READ = "read";
        private static final String ARGUMENT_WHERE = "--where";
        private static final String ARGUMENT_BIND = "--bind";
        private static final String ARGUMENT_URI = "--uri";
        private static final String ARGUMENT_USER = "--user";
        private static final String ARGUMENT_PROJECTION = "--projection";
        private static final String ARGUMENT_SORT = "--sort";
        private static final String ARGUMENT_METHOD = "--method";
        private static final String ARGUMENT_ARG = "--arg";
        private static final String ARGUMENT_EXTRA = "--extra";
        private static final String TYPE_BOOLEAN = "b";
        private static final String TYPE_STRING = "s";
        private static final String TYPE_INTEGER = "i";
        private static final String TYPE_LONG = "l";
        private static final String TYPE_FLOAT = "f";
        private static final String TYPE_DOUBLE = "d";
        private static final String COLON = ":";
        private static final String ARGUMENT_PREFIX = "--";

        private final Tokenizer mTokenizer;

        public Parser(String[] args) {
            mTokenizer = new Tokenizer(args);
        }

        public Command parseCommand() {
            try {
                String operation = mTokenizer.nextArg();
                if (ARGUMENT_INSERT.equals(operation)) {
                    return parseInsertCommand();
                } else if (ARGUMENT_DELETE.equals(operation)) {
                    return parseDeleteCommand();
                } else if (ARGUMENT_UPDATE.equals(operation)) {
                    return parseUpdateCommand();
                } else if (ARGUMENT_QUERY.equals(operation)) {
                    return parseQueryCommand();
                } else if (ARGUMENT_CALL.equals(operation)) {
                    return parseCallCommand();
                } else if (ARGUMENT_READ.equals(operation)) {
                    return parseReadCommand();
                } else {
                    throw new IllegalArgumentException("Unsupported operation: " + operation);
                }
            } catch (IllegalArgumentException iae) {
                System.out.println(USAGE);
                System.out.println("[ERROR] " + iae.getMessage());
                return null;
            }
        }

        private InsertCommand parseInsertCommand() {
            Uri uri = null;
            int userId = UserHandle.USER_OWNER;
            ContentValues values = new ContentValues();
            for (String argument; (argument = mTokenizer.nextArg()) != null;) {
                if (ARGUMENT_URI.equals(argument)) {
                    uri = Uri.parse(argumentValueRequired(argument));
                } else if (ARGUMENT_USER.equals(argument)) {
                    userId = Integer.parseInt(argumentValueRequired(argument));
                } else if (ARGUMENT_BIND.equals(argument)) {
                    parseBindValue(values);
                } else {
                    throw new IllegalArgumentException("Unsupported argument: " + argument);
                }
            }
            if (uri == null) {
                throw new IllegalArgumentException("Content provider URI not specified."
                        + " Did you specify --uri argument?");
            }
            if (values.size() == 0) {
                throw new IllegalArgumentException("Bindings not specified."
                        + " Did you specify --bind argument(s)?");
            }
            return new InsertCommand(uri, userId, values);
        }

        private DeleteCommand parseDeleteCommand() {
            Uri uri = null;
            int userId = UserHandle.USER_OWNER;
            String where = null;
            for (String argument; (argument = mTokenizer.nextArg())!= null;) {
                if (ARGUMENT_URI.equals(argument)) {
                    uri = Uri.parse(argumentValueRequired(argument));
                } else if (ARGUMENT_USER.equals(argument)) {
                    userId = Integer.parseInt(argumentValueRequired(argument));
                } else if (ARGUMENT_WHERE.equals(argument)) {
                    where = argumentValueRequired(argument);
                } else {
                    throw new IllegalArgumentException("Unsupported argument: " + argument);
                }
            }
            if (uri == null) {
                throw new IllegalArgumentException("Content provider URI not specified."
                        + " Did you specify --uri argument?");
            }
            return new DeleteCommand(uri, userId, where);
        }

        private UpdateCommand parseUpdateCommand() {
            Uri uri = null;
            int userId = UserHandle.USER_OWNER;
            String where = null;
            ContentValues values = new ContentValues();
            for (String argument; (argument = mTokenizer.nextArg())!= null;) {
                if (ARGUMENT_URI.equals(argument)) {
                    uri = Uri.parse(argumentValueRequired(argument));
                } else if (ARGUMENT_USER.equals(argument)) {
                    userId = Integer.parseInt(argumentValueRequired(argument));
                } else if (ARGUMENT_WHERE.equals(argument)) {
                    where = argumentValueRequired(argument);
                } else if (ARGUMENT_BIND.equals(argument)) {
                    parseBindValue(values);
                } else {
                    throw new IllegalArgumentException("Unsupported argument: " + argument);
                }
            }
            if (uri == null) {
                throw new IllegalArgumentException("Content provider URI not specified."
                        + " Did you specify --uri argument?");
            }
            if (values.size() == 0) {
                throw new IllegalArgumentException("Bindings not specified."
                        + " Did you specify --bind argument(s)?");
            }
            return new UpdateCommand(uri, userId, values, where);
        }

        public CallCommand parseCallCommand() {
            String method = null;
            int userId = UserHandle.USER_OWNER;
            String arg = null;
            Uri uri = null;
            ContentValues values = new ContentValues();
            for (String argument; (argument = mTokenizer.nextArg())!= null;) {
                if (ARGUMENT_URI.equals(argument)) {
                    uri = Uri.parse(argumentValueRequired(argument));
                } else if (ARGUMENT_USER.equals(argument)) {
                    userId = Integer.parseInt(argumentValueRequired(argument));
                } else if (ARGUMENT_METHOD.equals(argument)) {
                    method = argumentValueRequired(argument);
                } else if (ARGUMENT_ARG.equals(argument)) {
                    arg = argumentValueRequired(argument);
                } else if (ARGUMENT_EXTRA.equals(argument)) {
                    parseBindValue(values);
                } else {
                    throw new IllegalArgumentException("Unsupported argument: " + argument);
                }

            }
            if (uri == null) {
                throw new IllegalArgumentException("Content provider URI not specified."
                        + " Did you specify --uri argument?");
            }
            if (method == null) {
                throw new IllegalArgumentException("Content provider method not specified.");
            }
            return new CallCommand(uri, userId, method, arg, values);
        }

        private ReadCommand parseReadCommand() {
            Uri uri = null;
            int userId = UserHandle.USER_OWNER;
            for (String argument; (argument = mTokenizer.nextArg())!= null;) {
                if (ARGUMENT_URI.equals(argument)) {
                    uri = Uri.parse(argumentValueRequired(argument));
                } else if (ARGUMENT_USER.equals(argument)) {
                    userId = Integer.parseInt(argumentValueRequired(argument));
                } else {
                    throw new IllegalArgumentException("Unsupported argument: " + argument);
                }
            }
            if (uri == null) {
                throw new IllegalArgumentException("Content provider URI not specified."
                        + " Did you specify --uri argument?");
            }
            return new ReadCommand(uri, userId);
        }

        public QueryCommand parseQueryCommand() {
            Uri uri = null;
            int userId = UserHandle.USER_OWNER;
            String[] projection = null;
            String sort = null;
            String where = null;
            for (String argument; (argument = mTokenizer.nextArg())!= null;) {
                if (ARGUMENT_URI.equals(argument)) {
                    uri = Uri.parse(argumentValueRequired(argument));
                } else if (ARGUMENT_USER.equals(argument)) {
                    userId = Integer.parseInt(argumentValueRequired(argument));
                } else if (ARGUMENT_WHERE.equals(argument)) {
                    where = argumentValueRequired(argument);
                } else if (ARGUMENT_SORT.equals(argument)) {
                    sort = argumentValueRequired(argument);
                } else if (ARGUMENT_PROJECTION.equals(argument)) {
                    projection = argumentValueRequired(argument).split("[\\s]*:[\\s]*");
                } else {
                    throw new IllegalArgumentException("Unsupported argument: " + argument);
                }
            }
            if (uri == null) {
                throw new IllegalArgumentException("Content provider URI not specified."
                        + " Did you specify --uri argument?");
            }
            return new QueryCommand(uri, userId, projection, where, sort);
        }

        private void parseBindValue(ContentValues values) {
            String argument = mTokenizer.nextArg();
            if (TextUtils.isEmpty(argument)) {
                throw new IllegalArgumentException("Binding not well formed: " + argument);
            }
            final int firstColonIndex = argument.indexOf(COLON);
            if (firstColonIndex < 0) {
                throw new IllegalArgumentException("Binding not well formed: " + argument);
            }
            final int secondColonIndex = argument.indexOf(COLON, firstColonIndex + 1);
            if (secondColonIndex < 0) {
                throw new IllegalArgumentException("Binding not well formed: " + argument);
            }
            String column = argument.substring(0, firstColonIndex);
            String type = argument.substring(firstColonIndex + 1, secondColonIndex);
            String value = argument.substring(secondColonIndex + 1);
            if (TYPE_STRING.equals(type)) {
                values.put(column, value);
            } else if (TYPE_BOOLEAN.equalsIgnoreCase(type)) {
                values.put(column, Boolean.parseBoolean(value));
            } else if (TYPE_INTEGER.equalsIgnoreCase(type) || TYPE_LONG.equalsIgnoreCase(type)) {
                values.put(column, Long.parseLong(value));
            } else if (TYPE_FLOAT.equalsIgnoreCase(type) || TYPE_DOUBLE.equalsIgnoreCase(type)) {
                values.put(column, Double.parseDouble(value));
            } else {
                throw new IllegalArgumentException("Unsupported type: " + type);
            }
        }

        private String argumentValueRequired(String argument) {
            String value = mTokenizer.nextArg();
            if (TextUtils.isEmpty(value) || value.startsWith(ARGUMENT_PREFIX)) {
                throw new IllegalArgumentException("No value for argument: " + argument);
            }
            return value;
        }
    }

    private static class Tokenizer {
        private final String[] mArgs;
        private int mNextArg;

        public Tokenizer(String[] args) {
            mArgs = args;
        }

        private String nextArg() {
            if (mNextArg < mArgs.length) {
                return mArgs[mNextArg++];
            } else {
                return null;
            }
        }
    }

    private static abstract class Command {
        final Uri mUri;
        final int mUserId;

        public Command(Uri uri, int userId) {
            mUri = uri;
            mUserId = userId;
        }

        public final void execute() {
            String providerName = mUri.getAuthority();
            try {
                IActivityManager activityManager = ActivityManagerNative.getDefault();
                IContentProvider provider = null;
                IBinder token = new Binder();
                try {
                    ContentProviderHolder holder = activityManager.getContentProviderExternal(
                            providerName, mUserId, token);
                    if (holder == null) {
                        throw new IllegalStateException("Could not find provider: " + providerName);
                    }
                    provider = holder.provider;
                    onExecute(provider);
                } finally {
                    if (provider != null) {
                        activityManager.removeContentProviderExternal(providerName, token);
                    }
                }
            } catch (Exception e) {
                System.err.println("Error while accessing provider:" + providerName);
                e.printStackTrace();
            }
        }

        public static String resolveCallingPackage() {
            switch (Process.myUid()) {
                case Process.ROOT_UID: {
                    return "root";
                }

                case Process.SHELL_UID: {
                    return "com.android.shell";
                }

                default: {
                    return null;
                }
            }
        }

        protected abstract void onExecute(IContentProvider provider) throws Exception;
    }

    private static class InsertCommand extends Command {
        final ContentValues mContentValues;

        public InsertCommand(Uri uri, int userId, ContentValues contentValues) {
            super(uri, userId);
            mContentValues = contentValues;
        }

        @Override
        public void onExecute(IContentProvider provider) throws Exception {
            provider.insert(resolveCallingPackage(), mUri, mContentValues);
        }
    }

    private static class DeleteCommand extends Command {
        final String mWhere;

        public DeleteCommand(Uri uri, int userId, String where) {
            super(uri, userId);
            mWhere = where;
        }

        @Override
        public void onExecute(IContentProvider provider) throws Exception {
            provider.delete(resolveCallingPackage(), mUri, mWhere, null);
        }
    }

    private static class CallCommand extends Command {
        final String mMethod, mArg;
        Bundle mExtras = null;

        public CallCommand(Uri uri, int userId, String method, String arg, ContentValues values) {
            super(uri, userId);
            mMethod = method;
            mArg = arg;
            if (values != null) {
                mExtras = new Bundle();
                for (String key : values.keySet()) {
                    final Object val = values.get(key);
                    if (val instanceof String) {
                        mExtras.putString(key, (String) val);
                    } else if (val instanceof Float) {
                        mExtras.putFloat(key, (Float) val);
                    } else if (val instanceof Double) {
                        mExtras.putDouble(key, (Double) val);
                    } else if (val instanceof Boolean) {
                        mExtras.putBoolean(key, (Boolean) val);
                    } else if (val instanceof Integer) {
                        mExtras.putInt(key, (Integer) val);
                    } else if (val instanceof Long) {
                        mExtras.putLong(key, (Long) val);
                    }
                }
            }
        }

        @Override
        public void onExecute(IContentProvider provider) throws Exception {
            Bundle result = provider.call(null, mMethod, mArg, mExtras);
            final int size = result.size(); // unpack
            System.out.println("Result: " + result);
        }
    }

    private static class ReadCommand extends Command {
        public ReadCommand(Uri uri, int userId) {
            super(uri, userId);
        }

        @Override
        public void onExecute(IContentProvider provider) throws Exception {
            final ParcelFileDescriptor fd = provider.openFile(null, mUri, "r", null, null);
            copy(new FileInputStream(fd.getFileDescriptor()), System.out);
        }

        private static void copy(InputStream is, OutputStream os) throws IOException {
            final byte[] buffer = new byte[8 * 1024];
            int read;
            try {
                while ((read = is.read(buffer)) > -1) {
                    os.write(buffer, 0, read);
                }
            } finally {
                IoUtils.closeQuietly(is);
                IoUtils.closeQuietly(os);
            }
        }
    }

    private static class QueryCommand extends DeleteCommand {
        final String[] mProjection;
        final String mSortOrder;

        public QueryCommand(
                Uri uri, int userId, String[] projection, String where, String sortOrder) {
            super(uri, userId, where);
            mProjection = projection;
            mSortOrder = sortOrder;
        }

        @Override
        public void onExecute(IContentProvider provider) throws Exception {
            Cursor cursor = provider.query(resolveCallingPackage(), mUri, mProjection, mWhere,
                    null, mSortOrder, null);
            if (cursor == null) {
                System.out.println("No result found.");
                return;
            }
            try {
                if (cursor.moveToFirst()) {
                    int rowIndex = 0;
                    StringBuilder builder = new StringBuilder();
                    do {
                        builder.setLength(0);
                        builder.append("Row: ").append(rowIndex).append(" ");
                        rowIndex++;
                        final int columnCount = cursor.getColumnCount();
                        for (int i = 0; i < columnCount; i++) {
                            if (i > 0) {
                                builder.append(", ");
                            }
                            String columnName = cursor.getColumnName(i);
                            String columnValue = null;
                            final int columnIndex = cursor.getColumnIndex(columnName);
                            final int type = cursor.getType(columnIndex);
                            switch (type) {
                                case Cursor.FIELD_TYPE_FLOAT:
                                    columnValue = String.valueOf(cursor.getFloat(columnIndex));
                                    break;
                                case Cursor.FIELD_TYPE_INTEGER:
                                    columnValue = String.valueOf(cursor.getLong(columnIndex));
                                    break;
                                case Cursor.FIELD_TYPE_STRING:
                                    columnValue = cursor.getString(columnIndex);
                                    break;
                                case Cursor.FIELD_TYPE_BLOB:
                                    columnValue = "BLOB";
                                    break;
                                case Cursor.FIELD_TYPE_NULL:
                                    columnValue = "NULL";
                                    break;
                            }
                            builder.append(columnName).append("=").append(columnValue);
                        }
                        System.out.println(builder);
                    } while (cursor.moveToNext());
                } else {
                    System.out.println("No result found.");
                }
            } finally {
                cursor.close();
            }
        }
    }

    private static class UpdateCommand extends InsertCommand {
        final String mWhere;

        public UpdateCommand(Uri uri, int userId, ContentValues contentValues, String where) {
            super(uri, userId, contentValues);
            mWhere = where;
        }

        @Override
        public void onExecute(IContentProvider provider) throws Exception {
            provider.update(resolveCallingPackage(), mUri, mContentValues, mWhere, null);
        }
    }

    public static void main(String[] args) {
        Parser parser = new Parser(args);
        Command command = parser.parseCommand();
        if (command != null) {
            command.execute();
        }
    }
}
