package outils;import java.net.Socket;
import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.IOException;
import java.net.UnknownHostException;
import java.io.InputStreamReader;
import java.io.PrintStream;/**
Currently implemented commands:
help                                    display this help
listusers                               display existing accounts
countusers                              display the number of existing accounts
adduser [username] [password]           add a new user
verify [username]                       verify if specified user exist
deluser [username]                      delete existing user
setpassword [username] [password]       sets a user's password
setalias [username] [alias]             sets a user's alias
unsetalias [username]                   removes a user's alias
setforwarding [username] [emailaddress] forwards a user's email to another account
user [repositoryname]                   change to another user repository
shutdown                                kills the current JVM (convenient when James is run as a daemon)
quit                                    close connection * Describe class <code>JamesAdmin</code> here.
examples
countusers
   Existing accounts 8
listusers
  Existing accounts 8
  user: bob.hansen
  ...
verify don
  User don exist
verify jack
  User jack does not exist  
 *
 * @author <a href="mailto:[email protected]">Don Saxton</a>
 */
public class JamesAdmin {
    private String serverAddress = "localhost";
    private int port = 4555;
    private String userId = "root"; // administrators userid
    private String password = "root";    private Socket connectionSocket=null;
    private PrintStream out = System.err;
    private BufferedReader in = null;
    private boolean connectedStatus;
    
    public JamesAdmin()
    {
    }
    public JamesAdmin(String server, int port, String uid, String pwd)
    {
this.userId = uid;
this.password= pwd;
this.serverAddress = server;
this.port = port;

this.connectedStatus = connect();
    }    //methods
    public void ensure(String _userid, String _password, String _domain)
throws IOException 
    {
if (serverAddress.equalsIgnoreCase(_domain)){
    if (!isConnected()){
connect();
    }
    if(verifyUser(_userid)){ // user exists in james and changing password
if (null != _password && 0 < _password.length())
    changePassword(_userid, _password);
    }else
addUser(_userid, _password); // user was not in james and should
}else{
    if (!isConnected()){
connect();
    }
    if(verifyUser(_userid)){ // user exists in James and should not
delUser(_userid);
    }
}
    }        public boolean isConnected()
    {
return this.connectedStatus;
    }
    
    private void disconnect()
    {
try
    {
this.out.println("quit");
this.out.close();
this.in.close();
this.connectionSocket.close();
this.connectedStatus=false;
return;
    }
catch (IOException e) 
    {
this.connectedStatus=false;
log("Couldn't get I/O for "
   + "the connection to server.");
return;
    }
    }
    
    public boolean connect()
    {
try
    {
this.connectionSocket = new Socket(this.serverAddress, this.port);
this.out = new PrintStream(connectionSocket.getOutputStream(), true);
this.in = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
//Login to the server
String userInput;
log (in.readLine()); //wait for the connection
out.println(this.userId);//send userid
log(in.readLine());//wait for \n
out.println(this.password);//send the password
//log (in.readLine()); 
if ( in.readLine().indexOf("HELP") != -1 )
    {
this.connectedStatus=true;
log("Server accepted connection");
return true;
    }
else
    {
this.connectedStatus=false;
log("Server refused connection");
return false;
    }
    }
catch (UnknownHostException e) 
    {
this.connectedStatus=false;
log("Unable to connect to the host!");
return false;
    } 
catch (IOException e) 
    {
System.err.println("erreur officiel : \n"+e);
this.connectedStatus=false;
log("Couldn't get I/O for "
   + "the connection to server.");
return false;
    }
    }
    
    private String execute(String command)
throws IOException 
    {
String serverSays;
if (connectedStatus==false)
    connect();
// now execute the command
log("executing: -"+command+"-");
out.println(command);
out.println("###");
String returnString="";
char[] inChars = new char[1];
serverSays=in.readLine();
while( serverSays != null && serverSays.endsWith("###")==false ) 
    {
returnString += serverSays+"\n";
serverSays=in.readLine();
    }
// log("returning"+returnString);
return returnString;
    }    public boolean verifyUser(String userName)
throws IOException 
    {
if (!isConnected())
    connect();
if (!isConnected())
    log("broken"); // do something String response =execute("verify "+userName);            //   verify if specified user exist
boolean exists = false;
if (null != response && -1 == response.indexOf("does not"))
    exists = true;

return exists;
    }    public boolean addUser(String userName, String password)
throws IOException 
    {
if (!isConnected())
    connect();
if (!isConnected())
    log("broken: no connection to James"); // do something
String response = execute("adduser "+userName+" " + password);
boolean exists = false;
System.err.println("reponse : "+response);
if (null != response){
    if ( 0 <= response.indexOf("added")){
exists = true;
    }else if ( 0 <= response.indexOf("already")){
    exists = false;
    }
}
return exists;
     }    public boolean delUser(String _userName, String _domain)
throws IOException 
    {
if (serverAddress.equalsIgnoreCase(_domain)){
    return delUser(_userName);
}
return true; // well, he is not here!
    }    public boolean delUser(String userName)
throws IOException 
    {
if (!isConnected())
    connect();
if (!isConnected())
    log("broken"); // do something boolean exists = false; String response = execute("deluser "+userName+" " + password);
if (null != response){
}else if ( 0 <= response.indexOf("deleted")){
    exists = true;  // was deleted
}else if ( 0 <= response.indexOf("Error")){
    exists = true; // didn't exist

}
return exists;
    }    public boolean setPassword(String userName, String password)
throws IOException 
    {
if (!isConnected())
    connect();
if (!isConnected())
    log("broken"); // do something boolean exists = false; String response = execute("setpassword "+userName+" " + password);
if (null != response){
}else if ( 0 <= response.indexOf("reset")){
    exists = true;  // was deleted
}else if ( 0 <= response.indexOf("Error")){
    exists = true; // didn't exist

}
return exists;
    }    public boolean changePassword(String userName, String password)
throws IOException 
    {
//if (verifyUser(userName))  // james 2 added setpassword
//    delUser(userName);
return setPassword(userName,password);
    }
    private void log(String note){
System.err.println(getClass().getName()+" "+note);
    }
}