/*
 * 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.sling.jcr.jackrabbit.accessmanager.post;

import java.security.Principal;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.jcr.Item;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.servlet.Servlet;

import org.apache.jackrabbit.api.security.principal.PrincipalManager;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.ResourceNotFoundException;
import org.apache.sling.jcr.base.util.AccessControlUtil;
import org.apache.sling.jcr.jackrabbit.accessmanager.ModifyAce;
import org.apache.sling.servlets.post.AbstractPostResponse;
import org.apache.sling.servlets.post.Modification;
import org.osgi.service.component.annotations.Component;

/**
 * <p>
 * Sling Post Servlet implementation for modifying the ACEs for a principal on a JCR
 * resource.
 * </p>
 * <h2>Rest Service Description</h2>
 * <p>
 * Modify a principal's ACEs for the node identified as a resource by the request
 * URL &gt;resource&lt;.modifyAce.html
 * </p>
 * <h4>Methods</h4>
 * <ul>
 * <li>POST</li>
 * </ul>
 * <h4>Post Parameters</h4>
 * <dl>
 * <dt>principalId</dt>
 * <dd>The principal of the ACEs to modify in the ACL specified by the path.</dd>
 * <dt>privilege@*</dt>
 * <dd>One or more privileges, either granted or denied or none, which will be applied
 * to (or removed from) the node ACL. Any permissions that are present in an
 * existing ACE for the principal but not in the request are left untouched.</dd>
 * </dl>
 *
 * <h4>Response</h4>
 * <dl>
 * <dt>200</dt>
 * <dd>Success.</dd>
 * <dt>404</dt>
 * <dd>The resource was not found.</dd>
 * <dt>500</dt>
 * <dd>Failure. HTML explains the failure.</dd>
 * </dl>
 *
 * <h4>Notes</h4>
 * <p>
 * The principalId is assumed to refer directly to an Authorizable, that comes direct from
 * the UserManager. This can be a group or a user, but if its a group, denied permissions
 * will not be added to the group. The group will only contain granted privileges.
 * </p>
 */

@Component(service = {Servlet.class, ModifyAce.class},
property= {
		"sling.servlet.resourceTypes=sling/servlet/default",
		"sling.servlet.methods=POST",
		"sling.servlet.selectors=modifyAce"
})
public class ModifyAceServlet extends AbstractAccessPostServlet implements ModifyAce {
	private static final long serialVersionUID = -9182485466670280437L;

	/* (non-Javadoc)
	 * @see org.apache.sling.jackrabbit.accessmanager.post.AbstractAccessPostServlet#handleOperation(org.apache.sling.api.SlingHttpServletRequest, org.apache.sling.api.servlets.HtmlResponse, java.util.List)
	 */
	@Override
	protected void handleOperation(SlingHttpServletRequest request,
			AbstractPostResponse response, List<Modification> changes)
			throws RepositoryException {
		Session session = request.getResourceResolver().adaptTo(Session.class);
    	String resourcePath = request.getResource().getPath();
		String principalId = request.getParameter("principalId");
		Map<String, String> privileges = new HashMap<String, String>();
		Enumeration<?> parameterNames = request.getParameterNames();
		while (parameterNames.hasMoreElements()) {
			Object nextElement = parameterNames.nextElement();
			if (nextElement instanceof String) {
				String paramName = (String)nextElement;
				if (paramName.startsWith("privilege@")) {
					String privilegeName = paramName.substring(10);
					String parameterValue = request.getParameter(paramName);
					privileges.put(privilegeName, parameterValue);
				}
			}
		}
		String order = request.getParameter("order");
    	modifyAce(session, resourcePath, principalId, privileges, order);
	}
	
	/* (non-Javadoc)
	 * @see org.apache.sling.jcr.jackrabbit.accessmanager.ModifyAce#modifyAce(javax.jcr.Session, java.lang.String, java.lang.String, java.util.Map, java.lang.String)
	 */
	public void modifyAce(Session jcrSession, String resourcePath,
			String principalId, Map<String, String> privileges, String order)
			throws RepositoryException {
		if (jcrSession == null) {
			throw new RepositoryException("JCR Session not found");
		}

		if (principalId == null) {
			throw new RepositoryException("principalId was not submitted.");
		}
		PrincipalManager principalManager = AccessControlUtil.getPrincipalManager(jcrSession);
		Principal principal = principalManager.getPrincipal(principalId);
		
    	if (resourcePath == null) {
			throw new ResourceNotFoundException("Resource path was not supplied.");
    	}

		Item item = jcrSession.getItem(resourcePath);
		if (item != null) {
			resourcePath = item.getPath();
		} else {
			throw new ResourceNotFoundException("Resource is not a JCR Node");
		}
		
		// Collect the modified privileges from the request.
		Set<String> grantedPrivilegeNames = new HashSet<String>();
		Set<String> deniedPrivilegeNames = new HashSet<String>();
		Set<String> removedPrivilegeNames = new HashSet<String>();
		Set<Entry<String, String>> entrySet = privileges.entrySet();
		for (Entry<String, String> entry : entrySet) {
			String privilegeName = entry.getKey();
			if (privilegeName.startsWith("privilege@")) {
				privilegeName = privilegeName.substring(10);
			}
			String parameterValue = entry.getValue();
			if (parameterValue != null && parameterValue.length() > 0) {
				if ("granted".equals(parameterValue)) {
					grantedPrivilegeNames.add(privilegeName);
				} else if ("denied".equals(parameterValue)) {
					deniedPrivilegeNames.add(privilegeName);
				} else if ("none".equals(parameterValue)){
					removedPrivilegeNames.add(privilegeName);
				}
			}
		}

		// Make the actual changes.
		try {
			AccessControlUtil.replaceAccessControlEntry(jcrSession, resourcePath, principal,
					grantedPrivilegeNames.toArray(new String[grantedPrivilegeNames.size()]),
					deniedPrivilegeNames.toArray(new String[deniedPrivilegeNames.size()]),
					removedPrivilegeNames.toArray(new String[removedPrivilegeNames.size()]),
					order);
			if (jcrSession.hasPendingChanges()) {
				jcrSession.save();
			}
		} catch (RepositoryException re) {
			throw new RepositoryException("Failed to create ace.", re);
		}
	}
	
}
