/*
 * The MIT License (MIT)
 * 
 * Copyright (c) 2013-2014 Jeff Nelson, Cinchapi Software Collective
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.cinchapi.concourse.server.cli;

import org.cinchapi.concourse.server.jmx.ConcourseServerMXBean;

import com.beust.jcommander.Parameter;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;

/**
 * A management CLI to add/modify/remove user access to the server.
 * 
 * @author jnelson
 */
public class ManageUsersCli extends ManagedOperationCli {

    /**
     * Run the program...
     * 
     * @param args
     */
    public static void main(String... args) {
        ManageUsersCli cli = new ManageUsersCli(args);
        cli.run();
    }

    /**
     * Construct a new instance.
     * 
     * @param options
     * @param args
     */
    public ManageUsersCli(String[] args) {
        super(new MyOptions(), args);
    }

    @Override
    protected void doTask(ConcourseServerMXBean bean) {
        MyOptions opts = (MyOptions) options;
        try {
            if(opts.grant) {
                System.out.println("WARNING: Option --grant is being deprecated," +
                		" and replaced by options --add-user and --edit-user.");
                System.out.println("What is the username you want "
                        + "to add or modify?");
                byte[] username = console.readLine("").getBytes();
                System.out.println("What is the new password for this user?");
                byte[] password = console.readLine('*').getBytes();
                bean.grant(username, password);
                System.out.println("Consider it done.");
            }
            else if(opts.revoke) {
                System.out.println("WARNING: Option --revoke is being deprecated," +
                		" and replaced by option --delete-user.");
                System.out.println("What is the username you want to delete?");
                byte[] username = console.readLine("").getBytes();
                bean.revoke(username);
                System.out.println("Consider it done.");
            }
            else if(!Strings.isNullOrEmpty(opts.addingUsername)) {
                if(bean.hasUser(opts.addingUsername.getBytes())) {
                    System.out.println("WARNING: " +
                    		    opts.addingUsername + " already exists. " +
                    		    "Use CTRL-C to terminate or continue to edit this user.");
                }
                if(Strings.isNullOrEmpty(opts.newPassword)) {
                    opts.newPassword = console.readLine(
                            "Password for " + opts.addingUsername + " : ", '*');
                }
                bean.grant(opts.addingUsername.getBytes(), opts.newPassword.getBytes());
                System.out.println("Consider it done.");
            }
            else if(!Strings.isNullOrEmpty(opts.editingUsername)) {
                if(!bean.hasUser(opts.editingUsername.getBytes())) {
                    System.out.println("WARNING: " + 
                            opts.editingUsername + " does not exist. " +
                            "Use CTRL-C to terminate or continue to add this user.");   
                }
                if(Strings.isNullOrEmpty(opts.newPassword)) {
                    opts.newPassword = console.readLine(
                            "Password for " + opts.editingUsername + " : ", '*');
                }
                bean.grant(opts.editingUsername.getBytes(), opts.newPassword.getBytes());
                System.out.println("Consider it done.");
            }
            else if(!Strings.isNullOrEmpty(opts.deletingUsername)) {
                if(!bean.hasUser(opts.deletingUsername.getBytes())) {
                    System.out.println("WARNING: " + opts.deletingUsername + 
                            " does not exist.");
                }
                bean.revoke(opts.deletingUsername.getBytes());
                System.out.println("Consider it done.");
            }
            else {
                die("Action not found.\nTry `./useradmin --help` for more information.");
            }
        }
        catch (Exception e) {
            throw Throwables.propagate(e);
        }
        
    }

    /**
     * The options that can be passed to the main method of this script.
     * 
     * @author jnelson
     */
    private static class MyOptions extends Options {
        
        @Parameter(names = { "-g", "--grant" }, 
                description = "[DEPRECATED] Add a new user or change the password for an existing user. ")
        public boolean grant = false;

        @Parameter(names = { "-r", "--revoke" }, 
                description = "[DEPRECATED] Remove an existing user")
        public boolean revoke = false;

        @Parameter(names = { "-a", "--add-user" }, 
                description = "Username of new user to add.")
        public String addingUsername;
        
        @Parameter(names = { "-e", "--edit-user" }, 
                description = "Username of existing user to edit.")
        public String editingUsername;
        
        @Parameter(names = { "-d", "--delete-user" },
                description = "Username of existing user to delete.")
        public String deletingUsername;
        
        @Parameter(names = { "-np", "--new-password" },
                description = "Password of new user to add/edit.")
        public String newPassword;
        
    }

}

@@ -3309,67 +3309,25 @@
     
-System.out.println(%22WARNING: %22 +%0A                    %09%09    
+console.readLine(
 opts
@@ -3412,32 +3412,79 @@
 to terminate or 
+press RETURN to %22 +%0A                    %09%09    %22
 continue to edit
@@ -3476,23 +3476,23 @@
 ontinue 
-to 
 edit
+ing
  this us
@@ -4055,70 +4055,25 @@
     
-System.out.println(%22WARNING: %22 + %0A                            
+console.readLine(
 opts
@@ -4169,16 +4169,65 @@
 nate or 
+press RETURN to %22 +%0A                            %22
 continue
@@ -4227,22 +4227,22 @@
 ontinue 
-to 
 add
+ing
  this us
@@ -4831,22 +4831,8 @@
 tln(
-%22WARNING: %22 + 
 opts
@@ -4851,20 +4851,37 @@
 rname + 
-%0A   
+%22 does not exist.%22);%0A
         
@@ -4880,32 +4880,34 @@
                 
+%7D%0A
          %22 does 
@@ -4903,47 +4903,26 @@
     
-%22 does not exist.%22);%0A                %7D%0A
+       else %7B%0A    
     
@@ -4988,32 +4988,36 @@
                 
+    
 System.out.print
@@ -5033,32 +5033,50 @@
 der it done.%22);%0A
+                %7D%0A
             %7D%0A  

change warning messages from stdout output to console read and wait for user action