/* ======================================================================
   Parts Copyright 2006 University of Leeds, Oxford University, University of the Highlands and Islands.

   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.bodington.servlet.facilities;

import java.awt.Color;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Set;

import javax.servlet.ServletException;

import org.apache.log4j.Logger;
import org.bodington.server.BuildingContext;
import org.bodington.server.BuildingServerException;
import org.bodington.server.BuildingSession;
import org.bodington.server.BuildingSessionManagerImpl;
import org.bodington.server.realm.Group;
import org.bodington.server.realm.PassPhrase;
import org.bodington.server.realm.Permission;
import org.bodington.server.realm.User;
import org.bodington.server.resources.Resource;
import org.bodington.servlet.Request;
import org.bodington.util.BodingtonURL;

/**
 * Class used for display the current permissions of a resource.
 * Unlike typical Facilities this one doesn't subclass Facility as it only contains
 * static calls. It could all be in Facility but is in a seperate class so that we
 * don't bloat Facility too much.
 * @author buckett
 */
public class AclDisplayFacility
{
    
    private static Logger log = Logger.getLogger(AclDisplayFacility.class);
   
    
    /**
     * Display a table of permissions for the current resource.
     * We don't need to do any check as only people with VIEW access to the
     * resource will be able to see this page.
     * @param out The PrintWriter where the HTML is written.
     * @throws ServletException If we can't get the current resource.
     */
    public static void outputAclTable(PrintWriter out, Request request) throws ServletException
    {
        Set set;
        Enumeration permissions;
        Color highlightColor1, highlightColor2;
        Resource resource = request.getResource();
        try
        {
            AclResource aclResource = new AclResource(resource, resource
                .checkPermission(Permission.ADMINISTER)
                || resource.checkPermission(Permission.SYSADMIN));
            if (BuildingContext.getContext().getResource().checkPermission(Permission.MANAGE))
            {
                set = aclResource.getResults();
            }
            else 
            {
                set = aclResource.getResults((User)BuildingContext.getContext().getUser());
            }
            
            BuildingSession session = BuildingSessionManagerImpl.getSession(BuildingContext.getContext().getResource());
            highlightColor1 = session.getPropertyColor("style_navigation_menu_highlight_colour_1");
            highlightColor2 = session.getPropertyColor("style_navigation_menu_highlight_colour_2");

        }
        catch (BuildingServerException e)
        {
            throw new ServletException(e);
        }
        out.println("<table>");
        out.println("<tr>");
        out.println("<th>Name</th>");
        out.println("<th>Groups</th>");
        out.println("<th colspan=\"10\" style=\"text-align: center;\">Access Rights</th>");
       out.println("</tr>");

       
        Iterator rows =  set.iterator();
        
        
        boolean doHighlighting = !(highlightColor1 == null || highlightColor2 == null);
        int row = 0;
        while (rows.hasNext())
        {
            if (row % 10 == 0)
            {
                outputPermissionsHeader(out);
            }
            
            AclResourcePermission resourcePermission  = (AclResourcePermission)rows.next();
            if (doHighlighting)
            {
                out.println("<tr style=\"background-color: " + Utils.toCSSColor((row %2 == 0)?highlightColor1:highlightColor2) + "\">");
            }
            else 
            {
                out.println("<tr>");
            }
            
            
            out.print("<td>");
            if (resourcePermission.getUser() != null)
            {
                out.print(resourcePermission.getUser().getName());
                try
                {
                    PassPhrase pass = PassPhrase.findPassPhrase(resourcePermission.getUser());
                    if (pass != null)
                    {
                        out.print("<br/>");
                        out.print("<span style=\"font-size: 50%\">(");
                        out.print(pass.getUserName());
                        out.print(")</span>");
                    }
                }
                catch (BuildingServerException bse)
                {
                    ;
                }
            }
            
            out.println("</td>");
            
            out.print("<td>");
            Iterator groups = resourcePermission.getGroups();
            if (groups.hasNext()) {
                out.print(formatGroup((Group)groups.next(),  request));
                
                while(groups.hasNext())
                {
                    out.print(", ");
                    out.print(formatGroup((Group)groups.next(), request));
                }
            }
            out.println("</td>");
            
            permissions = Permission.permissions();
            while(permissions.hasMoreElements())
            {
                out.print("<td>");
                outputPermission(request, out, resourcePermission.hasPermission((Permission)permissions.nextElement()));
                out.println("</td>");
            }
            
            out.print("</tr>");

            row++;
        }
        
        out.println("</table>");
        
    }
    
    private static void outputPermission(Request request, PrintWriter out, boolean hasPermission)
    {
        out.write("<img src=\"");
		out.write(request.getContextPath());
		out.write("/icons/");
		out.write((hasPermission)?"smalltick.gif":"smallcross.gif");
		out.write("\" alt=\""+ ((hasPermission)?"Tick":"Cross") +"\"/>");
    }
    
    /**
     * Outputs the permissions header.
     * @param out
     */
    private static void outputPermissionsHeader(PrintWriter out)
    {
        out.println("<tr style=\"font-size: 50%;\">");
        out.println("<th colspan=\"2\"></th>");
        
        Enumeration permissions;
        permissions = Permission.permissions();
        
        while(permissions.hasMoreElements())
        {
               Object permission = permissions.nextElement();
               out.print("<th title=\"" + permission + "\">");
               out.print(permission);
               out.println("</th>");
        }
        out.println("</tr>");
    }

    /**
     * Format the group information in a HTML link. Display the URL for adhoc and owners 
     * groups and use the group name in all other cases.
     * @param group The group to display.
     * @return A HTML String linking to the group.
     */
    public static String formatGroup(Group group, Request request)
    {
        BodingtonURL url = new BodingtonURL( request );
        try
        {
            String groupURL = url.getResourceUrl(group.getResource())+ "bs_template_accessgroup.html?group_id="+ group.getPrimaryKey();
            String groupName;
            if (group.isLocalGroup())
            {
                groupName = group.getResource().getFullName() + group.getLocalName();
            }
            else
            {
                groupName = group.getName();
            }
            return "<a target=\"_new\" href=\""+groupURL+ "\">"+ groupName+"</a>";
        }
        catch (BuildingServerException bse)
        {
            log.warn("Problem trying to load group information.", bse);
        }
        
        return "";
        
    }

}
