/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  The ASF licenses this file to You
 * 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.  For additional information regarding
 * copyright in this work, please see the NOTICE file in the top level
 * directory of this distribution.
 */

package org.apache.roller.weblogger.ui.struts2.core;

import java.util.TimeZone;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.CharSetUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.roller.weblogger.WebloggerException;
import org.apache.roller.weblogger.business.WebloggerFactory;
import org.apache.roller.weblogger.business.UserManager;
import org.apache.roller.weblogger.config.AuthMethod;
import org.apache.roller.weblogger.config.WebloggerConfig;
import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
import org.apache.roller.weblogger.pojos.User;
import org.apache.roller.weblogger.ui.core.RollerSession;
import org.apache.roller.weblogger.ui.core.security.CustomUserRegistry;
import org.apache.roller.weblogger.ui.struts2.util.UIAction;
import org.apache.roller.weblogger.util.MailUtil;
import org.apache.struts2.convention.annotation.AllowedMethods;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.validation.SkipValidation;


/**
 * Actions for registering a new user.  This page is activated in Roller in two ways,
 * by explicitly selecting the "Register" button on the Main Menu, or if
 * upon a non-Roller DB login (say, LDAP) if the user does not exist in the
 * Roller DB.  In the latter case, this page is activated from login-redirect.jsp file.
 *
 * @see org.apache.roller.weblogger.ui.struts2.core.Login
 */
// TODO: make this work @AllowedMethods({"execute","save","activate"})
public class Register extends UIAction implements ServletRequestAware {
    
    private static Log log = LogFactory.getLog(Register.class);
    private static final String DISABLED_RETURN_CODE = "disabled";
    public static final String DEFAULT_ALLOWED_CHARS = "A-Za-z0-9";

    // this is a no-no, we should not need this
    private HttpServletRequest servletRequest = null;

    private AuthMethod authMethod = WebloggerConfig.getAuthMethod();

    private String activationStatus = null;
    
    private String activationCode = null;
    private ProfileBean bean = new ProfileBean();

    public Register() {
        this.pageTitle = "newUser.addNewUser";
    }
    
    // override default security, we do not require an authenticated user
    @Override
    public boolean isUserRequired() {
        return false;
    }
    
    // override default security, we do not require an action weblog
    @Override
    public boolean isWeblogRequired() {
        return false;
    }
    
    public String getAuthMethod() {
        return authMethod.name();
    }

    @SkipValidation
    @Override
    public String execute() {
        
        // if registration is disabled, then don't allow registration
        try {
            if (!WebloggerRuntimeConfig.getBooleanProperty("users.registration.enabled")
                // unless there are 0 users (need to allow creation of first user)
                && WebloggerFactory.getWeblogger().getUserManager().getUserCount() != 0) {
                addError("Register.disabled");
                return DISABLED_RETURN_CODE;
            }
        } catch (Exception e) {
            log.error("Error checking user count", e);
            addError("generic.error.check.logs");
            return DISABLED_RETURN_CODE;
        }
                
        // For new user default to locale set in browser
        bean.setLocale(getServletRequest().getLocale().toString());
        
        // For new user default to timezone of server
        bean.setTimeZone(TimeZone.getDefault().getID());
        
        /* TODO: when Spring Security 2.1 is release comment out this stuff, 
         * which pre-populates the user bean with info from OpenID provider.
         *
        Collection attrsCollect = (Collection)WebloggerFactory.getWeblogger()
                .getUserManager().userAttributes.get(UserAttribute.Attributes.openidUrl.toString());
        
        if (attrsCollect != null) {
            ArrayList attrs = new ArrayList(attrsCollect);
            for (OpenIDUserAttribute attr : attrs) {
                if (attr.getName().equals(OpenIDUserAttribute.Attributes.country.toString())) {
                    getBean().setLocale(UIUtils.getLocale(attr.getValue()));
                }                
               if (attr.getName().equals(OpenIDUserAttribute.Attributes.email.toString())) {
                    getBean().setEmailAddress(attr.getValue());
                }
                if (attr.getName().equals(OpenIDUserAttribute.Attributes.fullname.toString())) {
                    getBean().setFullName(attr.getValue());
                }
                if (attr.getName().equals(OpenIDUserAttribute.Attributes.nickname.toString())) {
                    getBean().setUserName(attr.getValue());
                }
                if (attr.getName().equals(OpenIDUserAttribute.Attributes.timezone.toString())) {
                    getBean().setTimeZone(UIUtils.getTimeZone(attr.getValue()));
                }
                if (attr.getName().equals(OpenIDUserAttribute.Attributes.openidname.toString())) {
                    getBean().setOpenidUrl(attr.getValue());
                }
                
            }
        }*/
            
        try {

            if (WebloggerConfig.getAuthMethod() == AuthMethod.LDAP) {
                // See if user is already logged in via Spring Security
                User fromSSOUser = CustomUserRegistry.getUserDetailsFromAuthentication(getServletRequest());
                if (fromSSOUser != null) {
                    // Copy user details from Spring Security, including LDAP attributes
                    getBean().copyFrom(fromSSOUser);
                }
            } else if (WebloggerConfig.getAuthMethod() == AuthMethod.CMA) {
                // See if user is already logged in via CMA
                if (getServletRequest().getUserPrincipal() != null) {
                    // Only detail we get is username, sadly no LDAP attributes
                    getBean().setUserName(getServletRequest().getUserPrincipal().getName());
                    getBean().setScreenName(getServletRequest().getUserPrincipal().getName());
                }
            }
            
        } catch (Exception ex) {
            log.error("Error reading SSO user data", ex);
            addError("error.editing.user", ex.toString());
        }
        
        return INPUT;
    }
    
    
    public String save() {
        
        // if registration is disabled, then don't allow registration
        try {
            if (!WebloggerRuntimeConfig.getBooleanProperty("users.registration.enabled")
                // unless there are 0 users (need to allow creation of first user)
                && WebloggerFactory.getWeblogger().getUserManager().getUserCount() != 0) {
                return DISABLED_RETURN_CODE;
            }
        } catch (Exception e) {
            log.error("Error checking user count", e);
            return DISABLED_RETURN_CODE;
        }
                
        myValidate();
        
        if (!hasActionErrors()) {
            try {

                UserManager mgr = WebloggerFactory.getWeblogger().getUserManager();

                // copy form data into new user pojo
                User ud = new User();
                // copyTo skips password
                getBean().copyTo(ud);
                ud.setUserName(getBean().getUserName());
                ud.setDateCreated(new java.util.Date());
                ud.setEnabled(Boolean.TRUE);

                // If user set both password and passwordConfirm then reset password
                if (!StringUtils.isEmpty(getBean().getPasswordText()) &&
                        !StringUtils.isEmpty(getBean().getPasswordConfirm())) {
                    ud.resetPassword(getBean().getPasswordText());
                }

                // are we using email activation?
                boolean activationEnabled = WebloggerRuntimeConfig.getBooleanProperty(
                        "user.account.email.activation");
                if (activationEnabled) {
                    // User account will be enabled after the activation process
                    ud.setEnabled(Boolean.FALSE);

                    // Create & save the activation data
                    String inActivationCode = UUID.randomUUID().toString();

                    inActivationCode = retryActivationCode(mgr, inActivationCode);
                    ud.setActivationCode(inActivationCode);
                }

                String openidurl = getBean().getOpenIdUrl();
                if (openidurl != null) {
                    if (openidurl.endsWith("/")) {
                        openidurl = openidurl.substring(0, openidurl.length() - 1);
                    }
                    ud.setOpenIdUrl(openidurl);
                }

                // save new user
                mgr.addUser(ud);

                WebloggerFactory.getWeblogger().flush();

                // now send activation email if necessary
                sendActivationMailIfNeeded(ud, activationEnabled);

                // Invalidate session, otherwise new user who was originally
                // authenticated via LDAP/SSO will remain logged in but
                // without a valid Roller role.
                getServletRequest().getSession().removeAttribute(RollerSession.ROLLER_SESSION);
                getServletRequest().getSession().invalidate();

                // set a special page title
                setPageTitle("welcome.title");

                return SUCCESS;

            } catch (WebloggerException ex) {
                log.error("Error adding new user", ex);
                addError("generic.error.check.logs");
            }
        }
        
        return INPUT;
    }

	private String retryActivationCode(UserManager mgr, String inActivationCode) throws WebloggerException {
		if (mgr.getUserByActivationCode(inActivationCode) != null) {
		    // In the *extremely* unlikely event that we generate an
		    // activation code that is already use, we'll retry 3 times.
		    int numOfRetries = 3;
		    if (numOfRetries < 1) {
		        numOfRetries = 1;
		    }
		    for (int i = 0; i < numOfRetries; i++) {
		        inActivationCode = UUID.randomUUID().toString();
		        if (mgr.getUserByActivationCode(inActivationCode) == null) {
		            break;
		        } else {
		            inActivationCode = null;
		        }
		    }
		    // In more unlikely event that three retries isn't enough
		    if (inActivationCode == null){
		        throw new WebloggerException("error.add.user.activationCodeInUse");
		    }
		}
		return inActivationCode;
	}

	private void sendActivationMailIfNeeded(User ud, boolean activationEnabled) {
		if (activationEnabled && ud.getActivationCode() != null) {
		    try {
		        // send activation mail to the user
		        MailUtil.sendUserActivationEmail(ud);
		    } catch (WebloggerException ex) {
		        log.error("Error sending activation email to - " + ud.getEmailAddress(), ex);
		    }

		    setActivationStatus("pending");
		}
	}
    
    
    @SkipValidation
    public String activate() {
        
        try {
            UserManager mgr = WebloggerFactory.getWeblogger().getUserManager();
            
            if (getActivationCode() == null) {
                addError("error.activate.user.missingActivationCode");
            } else {
                User user = mgr.getUserByActivationCode(getActivationCode());
                
                if (user != null) {
                    // enable user account
                    user.setEnabled(Boolean.TRUE);
                    user.setActivationCode(null);
                    mgr.saveUser(user);
                    WebloggerFactory.getWeblogger().flush();
                    
                    setActivationStatus("active");
                    
                } else {
                    addError("error.activate.user.invalidActivationCode");
                }
            }
            
        } catch (WebloggerException e) {
            addError(e.getMessage());
            log.error("ERROR in activateUser", e);
        }
        
        if (hasActionErrors()) {
            setActivationStatus("error");
        }
        
        // set a special page title
        setPageTitle("welcome.title");
            
        return SUCCESS;
    }
    
    
    public void myValidate() {
        
        // if using external auth, we don't want to error on empty password/username from HTML form.
        boolean usingSSO = authMethod == AuthMethod.LDAP || authMethod == AuthMethod.CMA;
        if (usingSSO) {
            // store an unused marker in the Roller DB for the passphrase in
            // the LDAP or CMA cases, as actual passwords are stored externally
            String unusedPassword = WebloggerConfig.getProperty("users.passwords.externalAuthValue", "<externalAuth>");
            
            // Preserve username and password, Spring Security case
            preserveUsernameAndPassword(unusedPassword);
        }
        
        String allowed = WebloggerConfig.getProperty("username.allowedChars");
        if (allowed == null || allowed.trim().length() == 0) {
            allowed = DEFAULT_ALLOWED_CHARS;
        }
        
        // check that username only contains safe characters
        String safe = CharSetUtils.keep(getBean().getUserName(), allowed);
        if (!safe.equals(getBean().getUserName()) ) {
            addError("error.add.user.badUserName");
        }
        
        // check password, it is required if OpenID and SSO are disabled
        if (AuthMethod.ROLLERDB.name().equals(getAuthMethod())
                && StringUtils.isEmpty(getBean().getPasswordText())) {
                addError("error.add.user.passwordEmpty");
                return;
        }
        
        // User.password does not allow null, so generate one
        if (getAuthMethod().equals(AuthMethod.OPENID.name()) ||
                (getAuthMethod().equals(AuthMethod.DB_OPENID.name()) && !StringUtils.isEmpty(getBean().getOpenIdUrl()))) {
            String randomString = RandomStringUtils.randomAlphanumeric(255);
            getBean().setPasswordText(randomString);
            getBean().setPasswordConfirm(randomString);
        }
        
        // check that passwords match 
        if (!getBean().getPasswordText().equals(getBean().getPasswordConfirm())) {
            addError("userRegister.error.mismatchedPasswords");
        }
        
        // check that username is not taken
        checkUsername();

        // check that OpenID, if provided, is not taken
        checkOpenID();
    }

	private void preserveUsernameAndPassword(String unusedPassword) {
		User fromSSOUser = CustomUserRegistry.getUserDetailsFromAuthentication(getServletRequest());
		if (fromSSOUser != null) {
		    getBean().setPasswordText(unusedPassword);
		    getBean().setPasswordConfirm(unusedPassword);
		    getBean().setUserName(fromSSOUser.getUserName());
		}

		// Preserve username and password, CMA case             
		else if (getServletRequest().getUserPrincipal() != null) {
		    getBean().setUserName(getServletRequest().getUserPrincipal().getName());
		    getBean().setPasswordText(unusedPassword);
		    getBean().setPasswordConfirm(unusedPassword);
		}
	}

	private void checkUsername() {
		if (!StringUtils.isEmpty(getBean().getUserName())) {
            try {
                UserManager mgr = WebloggerFactory.getWeblogger().getUserManager();
                if (mgr.getUserByUserName(getBean().getUserName(), null) != null) {
                    addError("error.add.user.userNameInUse");
                    // reset user name
                    getBean().setUserName(null);
                }
            } catch (WebloggerException ex) {
                log.error("error checking for user", ex);
                addError("generic.error.check.logs");
            }
        }
	}

	private void checkOpenID() {
		if (!StringUtils.isEmpty(getBean().getOpenIdUrl())) {
            try {
                UserManager mgr = WebloggerFactory.getWeblogger().getUserManager();
                if (mgr.getUserByOpenIdUrl(getBean().getOpenIdUrl()) != null) {
                    addError("error.add.user.openIdInUse");
                    // reset OpenID URL
                    getBean().setOpenIdUrl(null);
                }
            } catch (WebloggerException ex) {
                log.error("error checking OpenID URL", ex);
                addError("generic.error.check.logs");
            }
        }
	}
    
    
    public HttpServletRequest getServletRequest() {
        return servletRequest;
    }

    public void setServletRequest(HttpServletRequest servletRequest) {
        this.servletRequest = servletRequest;
    }
    
    public ProfileBean getBean() {
        return bean;
    }

    public void setBean(ProfileBean bean) {
        this.bean = bean;
    }

    public String getActivationStatus() {
        return activationStatus;
    }

    public void setActivationStatus(String activationStatus) {
        this.activationStatus = activationStatus;
    }

    public String getActivationCode() {
        return activationCode;
    }

    public void setActivationCode(String activationCode) {
        this.activationCode = activationCode;
    }
    
}
