/*
 * 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.editor;

import java.util.Collections;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.roller.weblogger.WebloggerException;
import org.apache.roller.weblogger.config.WebloggerConfig;
import org.apache.roller.weblogger.business.WebloggerFactory;
import org.apache.roller.weblogger.business.UserManager;
import org.apache.roller.weblogger.pojos.User;
import org.apache.roller.weblogger.pojos.WeblogPermission;
import org.apache.roller.weblogger.ui.struts2.util.UIAction;
import org.apache.roller.weblogger.util.MailUtil;
import org.apache.struts2.convention.annotation.AllowedMethods;


/**
 * Allows website admin to invite new members to website.
 *
 * TODO: handle 'disabled' result
 */
// TODO: make this work @AllowedMethods({"execute","save","cancel"})
public class MembersInvite extends UIAction {
    
    private static Log log = LogFactory.getLog(MembersInvite.class);
    
    // user being invited
    private String userName = null;
    
    // permissions being given to user
    private String permissionString = null;
    
    
    public MembersInvite() {
        this.actionName = "invite";
        this.desiredMenu = "editor";
        this.pageTitle = "inviteMember.title";
    }

    @Override
    public String execute() {
        
        // if group blogging is disabled then you can't change permissions
        if (!WebloggerConfig.getBooleanProperty("groupblogging.enabled")) {
            addError("inviteMember.disabled");
            return SUCCESS;
        }
        
        log.debug("Showing weblog invitation form");
        
        return INPUT;
    }
    
    
    /**
     * Save the new invitation and notify the user.
     */
    public String save() {
        
        // if group blogging is disabled then you can't change permissions
        if (!WebloggerConfig.getBooleanProperty("groupblogging.enabled")) {
            addError("inviteMember.disabled");
            return SUCCESS;
        }
        
        log.debug("Attempting to process weblog invitation");
        
        UserManager umgr = WebloggerFactory.getWeblogger().getUserManager();
        
        // user being invited
        User user = null;
        try {
            user = umgr.getUserByUserName(getUserName());
            if (user == null) {
                addError("inviteMember.error.userNotFound");
            }
        } catch(WebloggerException ex) {
            log.error("Error looking up user by id - "+getUserName(), ex);
            addError("Error looking up invitee");
        }
        
        // if we already have an error then bail now
        if(hasActionErrors()) {
            return INPUT;
        }
        
        // check for existing permissions or invitation
        try {
            WeblogPermission perm = umgr.getWeblogPermissionIncludingPending(getActionWeblog(), user);

            if (perm != null && perm.isPending()) {
                addError("inviteMember.error.userAlreadyInvited");
            } else if (perm != null) {
                addError("inviteMember.error.userAlreadyMember");
            }
            
        } catch (WebloggerException ex) {
            log.error("Error looking up permissions for weblog - "+getActionWeblog().getHandle(), ex);
            addError("Error checking existing permissions");
        }
        
        // if no errors then send the invitation
        if(!hasActionErrors()) {
            try {
                umgr.grantWeblogPermissionPending(getActionWeblog(), user,
                        Collections.singletonList(getPermissionString()));
                WebloggerFactory.getWeblogger().flush();

                addMessage("inviteMember.userInvited");

                if (MailUtil.isMailConfigured()) {
                    try {
                        MailUtil.sendWeblogInvitation(getActionWeblog(), user);
                    } catch (WebloggerException e) {
                        // TODO: this should be an error except that struts2 misbehaves
                        // when we chain this action to the next one thinking that an error
                        // means that validation broke during the chain
                        addMessage("error.untranslated", e.getMessage());
                    }
                }

                log.debug("Invitation successfully recorded");

                return SUCCESS;

            } catch (Exception ex) {
                log.error("Error creating user invitation", ex);
                addError("Error creating user invitation - check Roller logs");
            }
        }
        
        log.debug("Invitation had errors, giving user another chance");
        
        return INPUT;
    }
    
    /**
     * Cancel.
     * 
     * @return the string
     */
    @Override
    public String cancel() {
        return CANCEL;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userId) {
        this.userName = userId;
    }

    public String getPermissionString() {
        return permissionString;
    }

    public void setPermissionString(String permission) {
        this.permissionString = permission;
    }
    
}
