/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  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.
 *******************************************************************************/

package org.apache.ofbiz.workeffort.workeffort;

import java.io.IOException;
import java.io.Writer;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.UtilGenerics;
import org.apache.ofbiz.base.util.UtilHttp;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.base.util.UtilXml;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.util.EntityQuery;
import org.apache.ofbiz.service.GenericServiceException;
import org.apache.ofbiz.service.LocalDispatcher;
import org.apache.ofbiz.service.ServiceUtil;
import org.apache.ofbiz.webapp.stats.VisitHandler;
import org.apache.ofbiz.webapp.webdav.PropFindHelper;
import org.apache.ofbiz.webapp.webdav.ResponseHelper;
import org.apache.ofbiz.webapp.webdav.WebDavUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/** iCalendar worker class. This class handles the WebDAV requests and
 * delegates the calendar conversion tasks to <code>ICalConverter</code>.
 */
public final class ICalWorker {

    public static final String module = ICalWorker.class.getName();
    
    private ICalWorker() {};

    public static final class ResponseProperties {
        public final int statusCode;
        public final String statusMessage;
        public ResponseProperties(int statusCode, String statusMessage) {
            this.statusCode = statusCode;
            this.statusMessage = statusMessage;
        }
    }

    private static Map<String, Object> createConversionContext(HttpServletRequest request) {
        Map<String, Object> context = new HashMap<String, Object>();
        Enumeration<String> attributeEnum = UtilGenerics.cast(request.getAttributeNames());
        while (attributeEnum.hasMoreElements()) {
            String attributeName = attributeEnum.nextElement();
            context.put(attributeName, request.getAttribute(attributeName));
        }
        context.put("parameters", request.getParameterMap());
        context.put("locale", UtilHttp.getLocale(request));
        return context;
    }

    /** Create an HTTP Forbidden response. The calendar converter will use this
     * response when a user is logged in, but they don't have the basic CRUD
     * permissions to perform an action. Returning a Forbidden status will
     * prevent the client from trying the operation again.
     *
     * @param statusMessage Optional status message - usually <code>null</code>
     * for security reasons
     * @return Create an HTTP Forbidden response 
     */
    public static ResponseProperties createForbiddenResponse(String statusMessage) {
        return new ResponseProperties(HttpServletResponse.SC_FORBIDDEN, statusMessage);
    }

    /** Create an HTTP Unauthorized response. The calendar converter will use this
     * response when a user is not logged in, and basic CRUD permissions are
     * needed to perform an action. Returning an Unauthorized status will
     * force the client to authenticate the user, then try the operation again.
     *
     * @param statusMessage Optional status message - usually <code>null</code>
     * for security reasons
     * @return Create an HTTP Unauthorized response
     */
    public static ResponseProperties createNotAuthorizedResponse(String statusMessage) {
        return new ResponseProperties(HttpServletResponse.SC_UNAUTHORIZED, statusMessage);
    }

    public static ResponseProperties createNotFoundResponse(String statusMessage) {
        return new ResponseProperties(HttpServletResponse.SC_NOT_FOUND, statusMessage);
    }

    public static ResponseProperties createOkResponse(String statusMessage) {
        return new ResponseProperties(HttpServletResponse.SC_OK, statusMessage);
    }

    /** Create an HTTP Partial Content response. The calendar converter will use this
     * response when a calendar is only partially updated.
     *
     * @param statusMessage A message describing which calendar components were
     * not updated
     * @return Create an HTTP Partial Content response.
     */
    public static ResponseProperties createPartialContentResponse(String statusMessage) {
        return new ResponseProperties(HttpServletResponse.SC_PARTIAL_CONTENT, statusMessage);
    }

    private static Date getLastModifiedDate(HttpServletRequest request) throws GenericEntityException {
        String workEffortId = (String) request.getAttribute("workEffortId");
        Delegator delegator = (Delegator) request.getAttribute("delegator");
        GenericValue publishProperties = EntityQuery.use(delegator).from("WorkEffort").where("workEffortId", workEffortId).queryOne();
        GenericValue iCalData = publishProperties.getRelatedOne("WorkEffortIcalData", false);
        if (iCalData != null) {
            return iCalData.getTimestamp("lastUpdatedStamp");
        } else {
            return publishProperties.getTimestamp("lastUpdatedStamp");
        }
    }

    public static void handleGetRequest(HttpServletRequest request, HttpServletResponse response, ServletContext context) throws ServletException, IOException {
        if (!isValidRequest(request, response)) {
            return;
        }
        String workEffortId = (String) request.getAttribute("workEffortId");
        Debug.logInfo("[handleGetRequest] workEffortId = " + workEffortId, module);
        ResponseProperties responseProps = null;
        try {
            responseProps = ICalConverter.getICalendar(workEffortId, createConversionContext(request));
        } catch (Exception e) {
            Debug.logError(e, "[handleGetRequest] Error while sending calendar: ", module);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return;
        }
        if (responseProps.statusCode == HttpServletResponse.SC_OK) {
            response.setContentType("text/calendar");
        }
        writeResponse(responseProps, request, response, context);
    }

    public static void handlePropFindRequest(HttpServletRequest request, HttpServletResponse response, ServletContext context) throws ServletException, IOException {
        if (!isValidRequest(request, response)) {
            return;
        }
        String workEffortId = (String) request.getAttribute("workEffortId");
        Debug.logInfo("[handlePropFindRequest] workEffortId = " + workEffortId, module);
        try {
            Document requestDocument = WebDavUtil.getDocumentFromRequest(request);
            if (Debug.verboseOn()) {
                Debug.logVerbose("[handlePropFindRequest] PROPFIND body:\r\n" + UtilXml.writeXmlDocument(requestDocument), module);
            }
            PropFindHelper helper = new PropFindHelper(requestDocument);
            if (!helper.isAllProp() && !helper.isPropName()) {
                Document responseDocument = helper.getResponseDocument();
                List<Element> supportedProps = new LinkedList<Element>();
                List<Element> unSupportedProps = new LinkedList<Element>();
                List<Element> propElements = helper.getFindPropsList(ResponseHelper.DAV_NAMESPACE_URI);
                for (Element propElement : propElements) {
                    if ("getetag".equals(propElement.getNodeName())) {
                        Element etagElement = helper.createElementSetValue("D:getetag", String.valueOf(System.currentTimeMillis()));
                        supportedProps.add(etagElement);
                        continue;
                    }
                    if ("getlastmodified".equals(propElement.getNodeName())) {
                        Date lastModified = getLastModifiedDate(request);
                        Element lmElement = helper.createElementSetValue("D:getlastmodified", WebDavUtil.formatDate(WebDavUtil.getRFC1123DateFormat(), lastModified));
                        supportedProps.add(lmElement);
                        continue;
                    }
                    unSupportedProps.add(responseDocument.createElementNS(propElement.getNamespaceURI(), propElement.getTagName()));
                }
                Element responseElement = helper.createResponseElement();
                responseElement.appendChild(helper.createHrefElement("/" + workEffortId + "/"));
                if (supportedProps.size() > 0) {
                    Element propElement = helper.createPropElement(supportedProps);
                    responseElement.appendChild(helper.createPropStatElement(propElement, ResponseHelper.STATUS_200));
                }
                if (unSupportedProps.size() > 0) {
                    Element propElement = helper.createPropElement(unSupportedProps);
                    responseElement.appendChild(helper.createPropStatElement(propElement, ResponseHelper.STATUS_404));
                }
                Element rootElement = helper.createMultiStatusElement();
                rootElement.appendChild(responseElement);
                responseDocument.appendChild(rootElement);
                if (Debug.verboseOn()) {
                    Debug.logVerbose("[handlePropFindRequest] PROPFIND response:\r\n" + UtilXml.writeXmlDocument(responseDocument), module);
                }
                ResponseHelper.prepareResponse(response, 207, "Multi-Status");
                Writer writer = response.getWriter();
                try {
                    helper.writeResponse(response, writer);
                } finally {
                    writer.close();
                }
                return;
            }
        } catch (Exception e) {
            Debug.logError(e, "PROPFIND error: ", module);
        }
        response.setStatus(HttpServletResponse.SC_OK);
        response.flushBuffer();
    }

    public static void handlePutRequest(HttpServletRequest request, HttpServletResponse response, ServletContext context) throws ServletException, IOException {
        if (!isValidRequest(request, response)) {
            return;
        }
        String contentType = request.getContentType();
        if (contentType != null && !"text/calendar".equals(contentType)) {
            Debug.logInfo("[handlePutRequest] invalid content type", module);
            response.sendError(HttpServletResponse.SC_CONFLICT);
            return;
        }
        String workEffortId = (String) request.getAttribute("workEffortId");
        Debug.logInfo("[handlePutRequest] workEffortId = " + workEffortId, module);
        ResponseProperties responseProps = null;
        try {
            responseProps = ICalConverter.storeCalendar(request.getInputStream(), createConversionContext(request));
        } catch (Exception e) {
            Debug.logError(e, "[handlePutRequest] Error while updating calendar: ", module);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return;
        }
        writeResponse(responseProps, request, response, context);
    }

    private static boolean isValidRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {
        if (!request.isSecure()) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
            return false;
        }
        setupRequest(request, response);
        String workEffortId = (String) request.getAttribute("workEffortId");
        if (workEffortId == null) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
            return false;
        }
        return true;
    }

    private static void logInUser(HttpServletRequest request, HttpServletResponse response) throws GenericServiceException, GenericEntityException {
        Map<String, Object> serviceMap = WebDavUtil.getCredentialsFromRequest(request);
        if (serviceMap == null) {
            return;
        }
        serviceMap.put("locale", UtilHttp.getLocale(request));
        GenericValue userLogin = null;
        HttpSession session = request.getSession();
        LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");
        Map<String, Object> result = dispatcher.runSync("userLogin", serviceMap);
        if (ServiceUtil.isError(result) || ServiceUtil.isFailure(result)) {
            return;
        }
        userLogin = (GenericValue) result.get("userLogin");
        request.setAttribute("userLogin", userLogin);
        session.setAttribute("userLogin", userLogin);
        VisitHandler.getVisitor(request, response);
        GenericValue person = userLogin.getRelatedOne("Person", false);
        if (person != null) {
            request.setAttribute("person", person);
        } else {
            GenericValue partyGroup = userLogin.getRelatedOne("PartyGroup", false);
            if (partyGroup != null) {
                request.setAttribute("partyGroup", partyGroup);
            }
        }
    }

    private static void setupRequest(HttpServletRequest request, HttpServletResponse response) {
        String path = request.getPathInfo();
        if (UtilValidate.isEmpty(path)) {
            path = "/";
        }
        String workEffortId = path.substring(1);
        if (workEffortId.contains("/")) {
            workEffortId = workEffortId.substring(0, workEffortId.indexOf("/"));
        }
        if (workEffortId.length() < 1) {
            return;
        }
        request.setAttribute("workEffortId", workEffortId);
        try {
            logInUser(request, response);
        } catch (Exception e) {
            Debug.logError(e, "Error while logging in user: ", module);
        }
    }

    private static void writeResponse(ResponseProperties responseProps, HttpServletRequest request, HttpServletResponse response, ServletContext context) throws IOException {
        if (Debug.verboseOn()) {
            Debug.logVerbose("Returning response: code = " + responseProps.statusCode +
                    ", message = " + responseProps.statusMessage, module);
        }
        response.setStatus(responseProps.statusCode);
        if (responseProps.statusCode == HttpServletResponse.SC_UNAUTHORIZED) {
            response.setHeader("WWW-Authenticate", "Basic realm=\"OFBiz iCalendar " + request.getAttribute("workEffortId") + "\"");
        }
        if (responseProps.statusMessage != null) {
            response.setContentLength(responseProps.statusMessage.length());
            Writer writer = response.getWriter();
            try {
                writer.write(responseProps.statusMessage);
            } finally {
                writer.close();
            }
        }
    }
}
