/*
** Copyright 2014, 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.appwidget;

import android.content.Context;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.text.TextUtils;

import com.android.internal.appwidget.IAppWidgetService;

/**
 * This class is a command line utility for manipulating app widgets. A client
 * can grant or revoke the permission for a given package to bind app widgets.
 */
public class AppWidget {

    private static final String USAGE =
        "usage: adb shell appwidget [subcommand] [options]\n"
        + "\n"
        + "usage: adb shell appwidget grantbind --package <PACKAGE> "
                + " [--user <USER_ID> | current]\n"
        + "  <PACKAGE> an Android package name.\n"
        + "  <USER_ID> The user id under which the package is installed.\n"
        + "  Example:\n"
        + "  # Grant the \"foo.bar.baz\" package to bind app widgets for the current user.\n"
        + "  adb shell grantbind --package foo.bar.baz --user current\n"
        + "\n"
        + "usage: adb shell appwidget revokebind --package <PACKAGE> "
                + "[--user <USER_ID> | current]\n"
        + "  <PACKAGE> an Android package name.\n"
        + "  <USER_ID> The user id under which the package is installed.\n"
        + "  Example:\n"
        + "  # Revoke the permisison to bind app widgets from the \"foo.bar.baz\" package.\n"
        + "  adb shell revokebind --package foo.bar.baz --user current\n"
        + "\n";

    private static class Parser {
        private static final String ARGUMENT_GRANT_BIND = "grantbind";
        private static final String ARGUMENT_REVOKE_BIND = "revokebind";
        private static final String ARGUMENT_PACKAGE = "--package";
        private static final String ARGUMENT_USER = "--user";
        private static final String ARGUMENT_PREFIX = "--";
        private static final String VALUE_USER_CURRENT = "current";

        private final Tokenizer mTokenizer;

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

        public Runnable parseCommand() {
            try {
                String operation = mTokenizer.nextArg();
                if (ARGUMENT_GRANT_BIND.equals(operation)) {
                    return parseSetGrantBindAppWidgetPermissionCommand(true);
                } else if (ARGUMENT_REVOKE_BIND.equals(operation)) {
                    return parseSetGrantBindAppWidgetPermissionCommand(false);
                } else {
                    throw new IllegalArgumentException("Unsupported operation: " + operation);
                }
            } catch (IllegalArgumentException iae) {
                System.out.println(USAGE);
                System.out.println("[ERROR] " + iae.getMessage());
                return null;
            }
        }

        private SetBindAppWidgetPermissionCommand parseSetGrantBindAppWidgetPermissionCommand(
                boolean granted) {
            String packageName = null;
            int userId = UserHandle.USER_OWNER;
            for (String argument; (argument = mTokenizer.nextArg()) != null;) {
                if (ARGUMENT_PACKAGE.equals(argument)) {
                    packageName = argumentValueRequired(argument);
                } else if (ARGUMENT_USER.equals(argument)) {
                    String user = argumentValueRequired(argument);
                    if (VALUE_USER_CURRENT.equals(user)) {
                        userId = UserHandle.USER_CURRENT;
                    } else {
                        userId = Integer.parseInt(user);
                    }
                } else {
                    throw new IllegalArgumentException("Unsupported argument: " + argument);
                }
            }
            if (packageName == null) {
                throw new IllegalArgumentException("Package name not specified."
                        + " Did you specify --package argument?");
            }
            return new SetBindAppWidgetPermissionCommand(packageName, granted, userId);
        }

        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 class SetBindAppWidgetPermissionCommand implements Runnable {
        final String mPackageName;
        final boolean mGranted;
        final int mUserId;

        public SetBindAppWidgetPermissionCommand(String packageName, boolean granted,
                int userId) {
            mPackageName = packageName;
            mGranted = granted;
            mUserId = userId;
        }

        @Override
        public void run() {
            IBinder binder = ServiceManager.getService(Context.APPWIDGET_SERVICE);
            IAppWidgetService appWidgetService = IAppWidgetService.Stub.asInterface(binder);
            try {
                appWidgetService.setBindAppWidgetPermission(mPackageName, mUserId, mGranted);
            } catch (RemoteException re) {
                re.printStackTrace();
            }
        }
    }

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