package org.apache.slide.projector.processor.security;

import java.util.Map;

import org.apache.commons.contract.Context;
import org.apache.commons.contract.Information;
import org.apache.commons.contract.Processor;
import org.apache.commons.contract.Result;
import org.apache.commons.contract.constraints.StringConstraints;
import org.apache.commons.contract.descriptor.ParameterDescriptor;
import org.apache.commons.contract.descriptor.ResultDescriptor;
import org.apache.commons.contract.descriptor.ResultEntryDescriptor;
import org.apache.commons.contract.descriptor.StateDescriptor;
import org.apache.commons.contract.i18n.ParameterMessage;
import org.apache.commons.i18n.LocalizedError;
import org.apache.commons.i18n.LocalizedMessage;
import org.apache.slide.projector.Projector;
import org.apache.slide.projector.constraints.URIConstraints;
import org.apache.slide.projector.context.ProjectorContext;
import org.apache.slide.projector.repository.RepositoryException;

public class CreateUser implements Processor {
    private final static String USERNAME = "username";
    private final static String PASSWORD = "password";
    private final static String RETYPE_PASSWORD = "retypePassword";

    private final static String USER = "user";
    private final static String OK = "ok";
    private final static String FAILED = "failed";

    private final static ParameterDescriptor [] parameterDescriptor = new ParameterDescriptor[] {
            new ParameterDescriptor(USERNAME, new ParameterMessage("create-user/username"), new StringConstraints(1,24)),
            new ParameterDescriptor(PASSWORD, new ParameterMessage("create-user/password"), new StringConstraints(1,24)),
            new ParameterDescriptor(RETYPE_PASSWORD, new ParameterMessage("create-user/retyped-password"), new StringConstraints(1,24)),
        };

    private final static ResultDescriptor[] resultDescriptors = new ResultDescriptor[] {
            new ResultDescriptor(new StateDescriptor(OK, new LocalizedMessage("create-user/state/ok")),
                    new ResultEntryDescriptor[] {
                    new ResultEntryDescriptor(USER, new LocalizedMessage("createUser/result/user"), URIConstraints.UNCONSTRAINED)
            }),     
            new ResultDescriptor(new StateDescriptor(FAILED, new LocalizedMessage("create-user/state/failed")))
    		};

    public Result process(Map parameter, Context context) throws Exception {
        String username = parameter.get(USERNAME).toString();
        String retypedPassword = parameter.get(RETYPE_PASSWORD).toString();
        String password = parameter.get(PASSWORD).toString();
        String state = OK;
        Object user = null;
        if ( !password.equals(retypedPassword) ) {
            context.addInformation(new Information(Information.ERROR, new LocalizedError("register/passwordsNotIdentical"), new String[] { PASSWORD, RETYPE_PASSWORD }));
            state = FAILED;
        } else {
            try {
            	user = Projector.getRepository().createUser(username, password, ((ProjectorContext)context).getCredentials());	
            } catch ( RepositoryException exception ) {
                context.addInformation(new Information(Information.ERROR, exception.getLocalizedError(), new String[] { USERNAME }));
                state = FAILED;
            }
        }
        return new Result(state, USER, user);
    }

    public ParameterDescriptor[] getParameterDescriptors() {
    	return parameterDescriptor;
    }

    public ResultDescriptor[] getResultDescriptors() {
    	return resultDescriptors;
    }
}