/*
 * Copyright 2005 Sun Microsystems, Inc.
 *
 * Licensed 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.
 */

package org.apache.roller.weblogger.planet.ui;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.roller.RollerException;
import org.apache.roller.planet.business.PlanetManager;
import org.apache.roller.planet.business.fetcher.FeedFetcher;
import org.apache.roller.planet.business.fetcher.FetcherException;
import org.apache.roller.planet.pojos.Planet;
import org.apache.roller.planet.pojos.PlanetGroup;
import org.apache.roller.planet.pojos.Subscription;
import org.apache.roller.weblogger.business.WebloggerFactory;
import org.apache.roller.weblogger.pojos.GlobalPermission;
import org.apache.struts2.interceptor.ServletRequestAware;

import javax.servlet.http.HttpServletRequest;
import java.util.*;


/**
 * Manage planet group subscriptions, default group is "all".
 */
// TODO: make this work @AllowedMethods({"execute","saveSubscription","saveGroup","deleteSubscription"})
public class PlanetGroupSubs extends PlanetUIAction implements ServletRequestAware {

    private static final Log log = LogFactory.getLog(PlanetGroupSubs.class);

    // the planet group we are working in
    private PlanetGroup group = null;

    // the subscription to deal with
    private String subUrl = null;

    private Boolean createNew = null;

    public PlanetGroupSubs() {
        this.actionName = "planetGroupSubs";
        this.desiredMenu = "admin";
    }


    @Override
    public List<String> requiredGlobalPermissionActions() {
        return Collections.singletonList(GlobalPermission.ADMIN);
    }

    @Override
    public boolean isWeblogRequired() {
        return false;
    }


    @Override
    public void setServletRequest(HttpServletRequest request) {
        if (request.getParameter("createNew") != null) {
            group = new PlanetGroup();
        } else {
            group = getGroupFromRequest(request, getPlanet());
        }
    }


    static PlanetGroup getGroupFromRequest(HttpServletRequest request, Planet planet) {
        PlanetManager pmgr = WebloggerFactory.getWeblogger().getPlanetManager();
        PlanetGroup planetGroup = null;
        String action = null;
        try {
            if (request.getParameter("group.id") != null) {
                String groupId = request.getParameter("group.id");
                action = "looking up planet group by id: " + groupId;
                planetGroup = pmgr.getGroupById(groupId);

            } else if (request.getParameter("group.handle") != null) {
                String groupHandle = request.getParameter("group.handle");
                action = "looking up planet group by handle: " + groupHandle;
                planetGroup = pmgr.getGroup(planet, groupHandle);

            } else {
                action = "getting default group";
                planetGroup = pmgr.getGroup(planet, "all");
            }
        } catch (Exception ex) {
            log.error("Error " + action, ex);
        }
        return planetGroup;
    }

    /**
     * Populate page model and forward to subscription page
     */
    public String execute() {
        return LIST;
    }

    /**
     * Save group.
     */
    public String saveGroup() {

        validateGroup();

        if (!hasActionErrors()) {
            try {
                PlanetManager planetManager = WebloggerFactory.getWeblogger().getPlanetManager();

                PlanetGroup existingGroup = planetManager.getGroup(getPlanet(), getGroup().getHandle());

                if (existingGroup == null) {
                    log.debug("Adding New Group: " + getGroup().getHandle());
                    planetManager.saveNewPlanetGroup(getPlanet(), getGroup());

                } else {
                    log.debug("Updating Existing Group: " + existingGroup.getHandle());
                    existingGroup.setTitle( getGroup().getTitle() );
                    existingGroup.setHandle( getGroup().getHandle() );
                    planetManager.saveGroup(existingGroup);
                }

                WebloggerFactory.getWeblogger().flush();
                addMessage("planetGroups.success.saved");

            } catch (Exception ex) {
                log.error("Error saving planet group", ex);
                addError("planetGroups.error.saved");
            }
        }

        return LIST;
    }

    /**
     * Validate posted group
     */
    private void validateGroup() {

        if (StringUtils.isEmpty(getGroup().getTitle())) {
            addError("planetGroups.error.title");
        }

        if (StringUtils.isEmpty(getGroup().getHandle())) {
            addError("planetGroups.error.handle");
        }

        if (getGroup().getHandle() != null && "all".equals(getGroup().getHandle())) {
            addError("planetGroups.error.nameReserved");
        }

        // make sure duplicate group handles are prevented
    }


    /**
     * Save subscription, add to current group
     */
    public String saveSubscription() {

        valudateNewSub();

        if (!hasActionErrors()) {
            try {
                PlanetManager pmgr = WebloggerFactory.getWeblogger().getPlanetManager();

                // check if this subscription already exists before adding it
                Subscription sub = pmgr.getSubscription(getSubUrl());
                if (sub == null) {
                    log.debug("Adding New Subscription - " + getSubUrl());

                    // sub doesn't exist yet, so we need to fetch it
                    FeedFetcher fetcher = WebloggerFactory.getWeblogger().getFeedFetcher();
                    sub = fetcher.fetchSubscription(getSubUrl());

                    // save new sub
                    pmgr.saveSubscription(sub);

                } else {
                    // Subscription already exists
                    log.debug("Adding Existing Subscription - " + getSubUrl());
                }

                // add the sub to the group
                group.getSubscriptions().add(sub);
                sub.getGroups().add(group);
                pmgr.saveGroup(group);
                WebloggerFactory.getWeblogger().flush();

                // clear field after success
                setSubUrl(null);

                addMessage("planetSubscription.success.saved");

            } catch (FetcherException ex) {
                addError("planetGroupSubs.error.fetchingFeed", ex.getRootCauseMessage());

            } catch (RollerException ex) {
                log.error("Unexpected error saving subscription", ex);
                addError("planetGroupSubs.error.duringSave", ex.getRootCauseMessage());
            }
        }

        return LIST;
    }


    /**
     * Delete subscription, reset form
     */
    public String deleteSubscription() {

        if (getSubUrl() != null) {
            try {

                PlanetManager pmgr = WebloggerFactory.getWeblogger().getPlanetManager();

                Subscription sub = pmgr.getSubscription(getSubUrl());

                // remove sub from group
                getGroup().getSubscriptions().remove(sub);
                pmgr.saveGroup(getGroup());

                // remove group from sub
                sub.getGroups().remove(getGroup());
                pmgr.saveSubscription(sub);

                WebloggerFactory.getWeblogger().flush();

                // clear field after success
                setSubUrl(null);

                addMessage("planetSubscription.success.deleted");

            } catch (RollerException ex) {
                log.error("Error removing planet subscription", ex);
                addError("planetSubscription.error.deleting");
            }
        }

        return LIST;
    }


    /**
     * Validate posted subscription
     */
    private void valudateNewSub() {

        if (StringUtils.isEmpty(getSubUrl())) {
            addError("planetSubscription.error.feedUrl");
        }
    }


    @Override
    public String getPageTitle() {
        if (pageTitle == null) {
            if (getCreateNew()) {
                pageTitle = getText("planetGroupSubs.custom.title.new");
            } else if (getGroup().getHandle().equals("all")) {
                pageTitle = getText("planetGroupSubs.default.title");
            } else {
                pageTitle = getText("planetGroupSubs.custom.title", new String[]{getGroup().getHandle()});
            }
        }
        return pageTitle;
    }


    public List<Subscription> getSubscriptions() {

        List<Subscription> subs = Collections.emptyList();
        if (getGroup() != null) {
            Set<Subscription> subsSet = getGroup().getSubscriptions();

            // iterate over list and build display list
            subs = new ArrayList<>();
            for (Subscription sub : subsSet) {
                // only include external subs for display
                if (!sub.getFeedURL().startsWith("weblogger:")) {
                    subs.add(sub);
                }
            }
        }

        return subs;
    }

    public PlanetGroup getGroup() {
        return group;
    }

    public void setGroup(PlanetGroup group) {
        this.group = group;
    }

    public String getSubUrl() {
        return subUrl;
    }

    public void setSubUrl(String subUrl) {
        this.subUrl = subUrl;
    }

    public boolean getCreateNew() {
        if (createNew == null) {
            PlanetManager pmgr = WebloggerFactory.getWeblogger().getPlanetManager();
            PlanetGroup existingGroup = null;
            try {
                existingGroup = pmgr.getGroupById(group.getId());
            } catch (RollerException e) {
                log.error("Error getting group by ID", e);
            }
            createNew = (existingGroup == null);
        }
        return createNew;
    }

    public void setCreateNew(boolean createNew) {
        // no op
    }

    public String getGroupHandle() {
        return group.getHandle();
    }

}


