/*
 * 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.rendering.servlets;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.roller.util.RollerConstants;
import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
import org.apache.roller.planet.business.PlanetManager;
import org.apache.roller.planet.config.PlanetRuntimeConfig;
import org.apache.roller.planet.pojos.Planet;
import org.apache.roller.weblogger.business.WebloggerFactory;
import org.apache.roller.weblogger.pojos.StaticTemplate;
import org.apache.roller.weblogger.pojos.Template;
import org.apache.roller.weblogger.pojos.TemplateRendition.TemplateLanguage;
import org.apache.roller.weblogger.ui.rendering.Renderer;
import org.apache.roller.weblogger.ui.rendering.RendererManager;
import org.apache.roller.weblogger.ui.rendering.mobile.MobileDeviceRepository.DeviceType;
import org.apache.roller.weblogger.ui.rendering.model.UtilitiesModel;
import org.apache.roller.weblogger.ui.rendering.util.cache.PlanetCache;
import org.apache.roller.weblogger.ui.rendering.util.PlanetRequest;
import org.apache.roller.weblogger.ui.rendering.util.ModDateHeaderUtil;
import org.apache.roller.weblogger.util.cache.CachedContent;

/**
 * Planet Roller RSS feed.
 */
public class PlanetFeedServlet extends HttpServlet {

    private static Log log = LogFactory.getLog(PlanetFeedServlet.class);
    private PlanetCache planetCache = null;

    /**
     * Init method for this servlet
     */
    public void init(ServletConfig servletConfig) throws ServletException {

        super.init(servletConfig);

        log.info("Initializing PlanetRssServlet");

        this.planetCache = PlanetCache.getInstance();
    }

    /**
     * Handle GET requests for weblog pages.
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        log.debug("Entering");

        PlanetManager planet = WebloggerFactory.getWeblogger()
                .getPlanetManager();

        PlanetRequest planetRequest = null;
        try {
            planetRequest = new PlanetRequest(request);
        } catch (Exception e) {
            // some kind of error parsing the request
            log.debug("error creating planet request", e);
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }

        // figure planet last modified date
        Date lastModified = planetCache.getLastModified();

        // Respond with 304 Not Modified if it is not modified.
        if (ModDateHeaderUtil.respondIfNotModified(request, response,
                lastModified.getTime(), planetRequest.getDeviceType())) {
            return;
        }

        // set content type
        String accepts = request.getHeader("Accept");
        String userAgent = request.getHeader("User-Agent");
        if (accepts != null && userAgent != null
                && accepts.contains("*/*")
                && userAgent.startsWith("Mozilla")) {
            // client is a browser and now that we offer styled feeds we want
            // browsers to load the page rather than popping up the download
            // dialog, so we provide a content-type that browsers will display
            response.setContentType("text/xml");
        } else {
            response.setContentType("application/rss+xml; charset=utf-8");
        }

        // set last-modified date
        ModDateHeaderUtil.setLastModifiedHeader(response,
                lastModified.getTime(), planetRequest.getDeviceType());

        // cached content checking
        String cacheKey = PlanetCache.CACHE_ID + ":"
                + this.generateKey(planetRequest);
        CachedContent entry = (CachedContent) planetCache.get(cacheKey);
        if (entry != null) {
            response.setContentLength(entry.getContent().length);
            response.getOutputStream().write(entry.getContent());
            return;
        }

        // looks like we need to render content
        HashMap<String, Object> model = new HashMap<String, Object>();
        try {

            // populate the rendering model
            if (request.getParameter("group") != null) {
                Planet planetObject = planet.getWeblogger("default");
                model.put(
                        "group",
                        planet.getGroup(planetObject,
                                request.getParameter("group")));
            }

            model.put("planet", planet);
            model.put("date", new Date());
            model.put("utils", new UtilitiesModel());
            model.put("lastModified", lastModified);

            model.put("siteName",
                    PlanetRuntimeConfig.getProperty("planet.site.name"));

            model.put("siteDescription",
                    PlanetRuntimeConfig.getProperty("planet.site.description"));


            if (StringUtils.isNotEmpty(WebloggerRuntimeConfig
                    .getProperty("planet.site.absoluteurl"))) {
                model.put("absoluteSite",
                        PlanetRuntimeConfig.getProperty("planet.site.absoluteurl"));
            } else {
                model.put("absoluteSite",
                        WebloggerRuntimeConfig.getAbsoluteContextURL());
            }

            model.put("feedStyle", WebloggerRuntimeConfig
                    .getBooleanProperty("site.newsfeeds.styledFeeds"));

            int numEntries = WebloggerRuntimeConfig
                    .getIntProperty("site.newsfeeds.defaultEntries");

            int entryCount = numEntries;
            String sCount = request.getParameter("count");
            if (sCount != null) {
                try {
                    entryCount = Integer.parseInt(sCount);
                } catch (NumberFormatException e) {
                    log.warn("Improperly formatted count parameter");
                }
                if (entryCount > numEntries) {
                    entryCount = numEntries;
                }
                if (entryCount < 0) {
                    entryCount = 0;
                }
            }
            model.put("entryCount", entryCount);
        } catch (Exception ex) {
            log.error("Error loading model objects for page", ex);

            if (!response.isCommitted()) {
                response.reset();
            }
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return;
        }

        // lookup Renderer we are going to use
        Renderer renderer = null;
        try {
            log.debug("Looking up renderer");
            Template template = new StaticTemplate(
                    "templates/planet/planetrss.vm", TemplateLanguage.VELOCITY);
            renderer = RendererManager.getRenderer(template, DeviceType.mobile);
        } catch (Exception e) {
            // nobody wants to render my content :(
            log.error("Couldn't find renderer for planet rss", e);

            if (!response.isCommitted()) {
                response.reset();
            }
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }

        // render content
        CachedContent rendererOutput = new CachedContent(RollerConstants.TWENTYFOUR_KB_IN_BYTES);
        try {
            log.debug("Doing rendering");
            renderer.render(model, rendererOutput.getCachedWriter());

            // flush rendered output and close
            rendererOutput.flush();
            rendererOutput.close();
        } catch (Exception e) {
            // bummer, error during rendering
            log.error("Error during rendering for planet rss", e);

            if (!response.isCommitted()) {
                response.reset();
            }
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }

        // post rendering process
        // flush rendered content to response
        log.debug("Flushing response output");
        response.setContentLength(rendererOutput.getContent().length);
        response.getOutputStream().write(rendererOutput.getContent());

        // cache rendered content.
        this.planetCache.put(cacheKey, rendererOutput);

        log.debug("Exiting");
    }

    /**
     * Generate a cache key from a parsed planet request. This generates a key
     * of the form ...
     * 
     * <context>/<type>/<language>[/user] or
     * <context>/<type>[/flavor]/<language>[/excerpts]
     * 
     * 
     * examples ...
     * 
     * planet/page/en planet/feed/rss/en/excerpts
     * 
     */
    private String generateKey(PlanetRequest planetRequest) {

        StringBuilder key = new StringBuilder();
        key.append(planetRequest.getContext());
        key.append("/");
        key.append(planetRequest.getType());

        if (planetRequest.getFlavor() != null) {
            key.append("/").append(planetRequest.getFlavor());
        }

        // add language
        key.append("/").append(planetRequest.getLanguage());

        if (planetRequest.getFlavor() != null) {
            // add excerpts
            if (planetRequest.isExcerpts()) {
                key.append("/excerpts");
            }
        } else {
            // add login state
            if (planetRequest.getAuthenticUser() != null) {
                key.append("/user=").append(planetRequest.getAuthenticUser());
            }
        }

        // add group
        if (planetRequest.getGroup() != null) {
            key.append("/group=").append(planetRequest.getGroup());
        }

        return key.toString();
    }
}