package edu.harvard.iq.dataverse.api;

import edu.harvard.iq.dataverse.authorization.providers.builtin.BuiltinAuthenticationProvider;
import edu.harvard.iq.dataverse.authorization.providers.builtin.BuiltinUser;
import edu.harvard.iq.dataverse.authorization.providers.builtin.BuiltinUserServiceBean;
import edu.harvard.iq.dataverse.authorization.users.ApiToken;
import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser;
import static edu.harvard.iq.dataverse.util.json.JsonPrinter.json;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

/**
 * REST API bean for managing {@link BuiltinUser}s.
 * @author michael
 */
@Path("users")
public class BuiltinUsers extends AbstractApiBean {
	private static final Logger logger = Logger.getLogger(BuiltinUsers.class.getName());
	
    private static final String API_KEY_IN_SETTINGS = "BuiltinUsers.KEY";
    
    @EJB
	protected BuiltinUserServiceBean builtinUserSvc;
    
	@GET
	public Response list(@QueryParam("key") String key ) {
        String expectedKey = settingsSvc.get( API_KEY_IN_SETTINGS );
        if ( expectedKey==null ) {
            return errorResponse(Status.SERVICE_UNAVAILABLE, "Dataverse config issue: No API key defined for built in user management");
        }
        if ( ! expectedKey.equals(key) ) {
            return badApiKey(key);
        }
		JsonArrayBuilder bld = Json.createArrayBuilder();
		
		for ( BuiltinUser u : builtinUserSvc.findAll() ) {
			bld.add( json(u) );
		}
		
		return okResponse( bld );
	}
	
	@POST
	public Response save( BuiltinUser user, @QueryParam("password") String password, @QueryParam("key") String key ) {
        String expectedKey = settingsSvc.get( API_KEY_IN_SETTINGS );
        if ( expectedKey==null ) {
            return errorResponse(Status.SERVICE_UNAVAILABLE, "Dataverse config issue: No API key defined for built in user management");
        }
        if ( ! expectedKey.equals(key) ) {
            return badApiKey(key);
        }
		try { 
			if ( password != null ) {
				user.setEncryptedPassword(builtinUserSvc.encryptPassword(password));
			}
			user = builtinUserSvc.save(user);
            
            AuthenticatedUser au = authSvc.createAuthenticatedUser(BuiltinAuthenticationProvider.PROVIDER_ID, user.getUserName(), user.createDisplayInfo());
            
            ApiToken token = new ApiToken();
            
            token.setTokenString(java.util.UUID.randomUUID().toString());
            token.setAuthenticatedUser(au);

            Calendar c = Calendar.getInstance();
            token.setCreateTime( new Timestamp(c.getTimeInMillis()) );
            c.roll(Calendar.YEAR, 1);
            token.setExpireTime( new Timestamp(c.getTimeInMillis()) );
            authSvc.save(token);
            
            JsonObjectBuilder resp = Json.createObjectBuilder();
            resp.add("user", json(user) );
            resp.add("apiToken", token.getTokenString());
			return okResponse( resp );
            
		} catch ( Exception e ) {
			logger.log( Level.WARNING, "Error saving user", e );
			return errorResponse( Status.INTERNAL_SERVER_ERROR, "Can't save user: " + e.getMessage() );
		}
	}

}

@@ -804,16 +804,46 @@
 s.Path;%0A
+import javax.ws.rs.PathParam;%0A
 import j
@@ -1892,18 +1892,460 @@
 %0A%09%7D%0A
-%09%0A%09@POST%0A%09
+        %0A        /**%0A         * Created this new API command because the save method could not be run from the RestAssured API.  RestAssured doesn't%0A         * allow a Post request to contain both a body and request parameters.%0A         * TODO: replace current usage of save() with create?%0A         * @param user%0A         * @param password%0A         * @param key%0A         * @return %0A         */%0A        @POST%0A        @Path(%22%7Bpassword%7D/%7Bkey%7D%22)  %0A        
 publ
@@ -2360,14 +2360,15 @@
 nse 
-sav
+creat
 e(
- 
 Buil
@@ -2382,21 +2382,20 @@
  user, @
-Query
+Path
 Param(%22p
@@ -2422,21 +2422,20 @@
 sword, @
-Query
+Path
 Param(%22k
@@ -2446,32 +2446,188 @@
  String key ) %7B%0A
+            return internalSave(user, password,key);%0A        %7D%0A%09%0A        private Response internalSave(BuiltinUser user, String password,String key) %7B%0A     
         String e
@@ -4129,14 +4129,213 @@
  );%0A%09%09%7D%0A
+        %7D%0A        %0A%09@POST     %0A%09public Response save( BuiltinUser user, @QueryParam(%22password%22) String password, @QueryParam(%22key%22) String key ) %7B%0A            return internalSave(user,password,key);%0A
 %09%7D%0A%0A%7D%0A

Create API Command for creating a user, without query parameters