/*
 * 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 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.BookmarkManager;
import org.apache.roller.weblogger.business.WebloggerFactory;
import org.apache.roller.weblogger.pojos.WeblogBookmark;
import org.apache.roller.weblogger.ui.struts2.util.UIAction;
import org.apache.roller.weblogger.util.cache.CacheManager;
import org.apache.struts2.convention.annotation.AllowedMethods;
import org.apache.struts2.interceptor.validation.SkipValidation;


/**
 * Edit a new or existing bookmark (blogroll item).
 */
// TODO: make this work @AllowedMethods({"execute","save"})
public class BookmarkEdit extends UIAction {
    
    private static Log log = LogFactory.getLog(BookmarkEdit.class);

    // bean for managing form data
    private BookmarkBean bean = new BookmarkBean();

    // the id of the folder holding the bookmark
    private String folderId = null;

    // the bookmark we are adding or editing
    private WeblogBookmark bookmark = null;


    public BookmarkEdit() {
        this.desiredMenu = "editor";
    }

    @Override
    public void setPageTitle(String pageTitle) {
        this.pageTitle = pageTitle;
    }

    @Override
    public void myPrepare() {
        if (StringUtils.isEmpty(bean.getId())) {
            // Create and initialize new, not-yet-saved WeblogBookmark
            bookmark = new WeblogBookmark();
            BookmarkManager bmgr = WebloggerFactory.getWeblogger().getBookmarkManager();
            try {
                if (!StringUtils.isEmpty(getFolderId())) {
                    bookmark.setFolder(bmgr.getFolder(getFolderId()));
                }
            } catch (WebloggerException ex) {
                addError("generic.error.check.logs");
                log.error("Error looking up folder", ex);
            }
        } else {
            // existing bookmark, retrieve its info from DB
            try {
                BookmarkManager bmgr = WebloggerFactory.getWeblogger().getBookmarkManager();
                bookmark = bmgr.getBookmark(getBean().getId());
            } catch (WebloggerException ex) {
                addError("generic.error.check.logs");
                log.error("Error looking up bookmark" + getBean().getId(), ex);
            }
        }
    }
    
    
    @SkipValidation
    @Override
    public String execute() {
        if (!isAdd()) {
            // load bean with database values during initial load
            getBean().copyFrom(getBookmark());
        }
        return INPUT;
    }

    
    public String save() {
        myValidate();

        if (!hasActionErrors()) {
            try {
                getBean().copyTo(bookmark);
                BookmarkManager bmgr = WebloggerFactory.getWeblogger().getBookmarkManager();
                bmgr.saveBookmark(bookmark);
                WebloggerFactory.getWeblogger().flush();
                CacheManager.invalidate(bookmark);
                addMessage(isAdd() ? "bookmarkForm.created" : "bookmarkForm.updated", getBookmark().getName());
                return SUCCESS;

            } catch(Exception ex) {
                log.error("Error saving bookmark", ex);
                addError("generic.error.check.logs");
            }
        }
        
        return INPUT;
    }

    public void myValidate() {
        // if name new or changed, check new name doesn't already exist
        if ((isAdd() || !getBean().getName().equals(bookmark.getName()))
             && bookmark.getFolder().hasBookmarkOfName(getBean().getName())) {
                addError("bookmarkForm.error.duplicateName", getBean().getUrl());
        }
    }

    private boolean isAdd() {
        return actionName.equals("bookmarkAdd");
    }

    public String getFolderId() {
        return folderId;
    }

    public void setFolderId(String folderId) {
        this.folderId = folderId;
    }
    
    public BookmarkBean getBean() {
        return bean;
    }

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

    // getter needed because JSP reads this object in order to obtain folder name
    public WeblogBookmark getBookmark() {
        return bookmark;
    }

}
