/* ======================================================================
   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 org.apache.log4j.Logger;

import org.bodington.servlet.*;

import java.io.*;
import java.util.*;

import javax.servlet.*;
import javax.servlet.http.*;
import java.sql.*;

import org.bodington.server.BuildingContext;
import org.bodington.server.BuildingServerException;
import org.bodington.server.realm.Group;
import org.bodington.server.realm.Permission;
import org.bodington.server.resources.Resource;

public class PermissionFacility extends org.bodington.servlet.facilities.Facility
	{
	
    private static Logger log = Logger.getLogger(PermissionFacility.class);

	static final int LISTSTYLE_NORMAL=0;
	static final int LISTSTYLE_DELETE=1;
	static final int LISTSTYLE_SID=2;
	static final int LISTSTYLE_UID=3;
	static final int LISTSTYLE_SURNAME=4;
	static final int LISTSTYLE_MODULE=5;

	static private int container_facility_no=27;

	/**
     * Group editors and group containers will refuse to be initialised
     *
     * @param original The resource with properties to copy.
     * @param new_resource The resource to initialise.
     * @return True if initialisation was OK.
     * @exception BuildingServerException Thrown if there is any problem initialising the resource.
     *
     */
	public boolean initResource( Resource original, Resource new_resource)
		throws BuildingServerException
    {
        return false;
    }


	public String getPrefix()
		throws BuildingServerException
		{
		StringBuffer name = new StringBuffer();
		boolean in_groups;
		BuildingContext context=BuildingContext.getContext();
		Resource resource = context.getResource();
		Resource current;
		Enumeration ancestors = resource.findAncestors();
		
		in_groups=false;
		while ( ancestors.hasMoreElements() )
			{
			current = (Resource)ancestors.nextElement();
			if ( in_groups )
				{
				if ( current.getHttpFacilityNo() != 27  )
					{
					in_groups=false;
					name.setLength( 0 );
					continue;
					}
				name.append( current.getName() );
				name.append( "." );
				}
			else
				{
				if ( current.getHttpFacilityNo()==27 )
					{
					in_groups=true;
					name.setLength( 0 );
					name.append( current.getName() );
					name.append( "." );
					}
				}
			}
		return name.toString();
		}


	public List validate( Resource newResource ) throws BuildingServerException
	{
	    List errors = new LinkedList();
	    String name = newResource.getName();
	    String prefix = getPrefix();
	    if ( prefix==null || prefix.length()<1 )
	    {
	        errors.add("Unexpected technical problem - unable to determine prefix for group name.");
	    }
	    else
	    {
	        name = prefix + name;
	        if ( name.length()>64 )
	        {
	            errors.add( 
	                "The full name of the group, " + name + 
	            "is more than the allowed 64 characters in length." );
	        }
	    }
	    String description = newResource.getDescription();
	    if (description == null || description.length()>128)
	    {
	        errors.add("Description cannot be more that 128 characters, you currenlty have "+ description.length()+ " characters.");
	    }

	    errors.addAll(super.validate(newResource));
	    return errors;
	}

	public List postCreate( Request breq, Resource newResource )
		throws Exception
		{
	    List errors = super.postCreate(breq, newResource);
	    
		String prefix = getPrefix();
        log.debug( "Prefix = [" + prefix + "]" );
		if ( prefix==null || prefix.length()<1 )
			{
		    errors = new ArrayList(errors);
			errors.add("Prefix for group cannot be empty.");
			return errors;
			}
        Integer special = null;
        if (breq.getParameter("special")!= null && breq.getResource().checkPermission(Permission.SYSADMIN))
        {
            Connection con = BuildingContext.getContext().getConnection();
            PreparedStatement stmt = con.prepareStatement("select max(special_group) from groups");
            ResultSet results = stmt.executeQuery(); 
            if (results.next())
            { 
                special = new Integer(results.getInt(1)+1);
                log.debug("Creating a special group. New Num: " + special);
            }
            else
            {
                special = new Integer(1);
            }
        }
        
		String name = prefix + newResource.getName();
			
		Group group=new Group();
		group.setResourceId( newResource.getResourceId() );
		group.setName( name );
		group.setDescription( newResource.getDescription() );
        group.setSpecialGroup(special);
		newResource.setTitle( group.getName() );
		newResource.save();
		group.save();
		
		return errors;  
		}

	public boolean clearCacheEntry( Object d, boolean force )
		{
		//no special clean up needed
		return true;
		}

	public void insert( Request req, PrintWriter out, String command, String insertname )
		throws ServletException, IOException
		{
		log.debug( " PermissionFacility insert()" );
			
		try
			{
			if ( command.equals( "grouptable" ) )
				{
				groupTable( req, out );
				return;
				}
			if ( command.equals( "confirmaddgroup" ) )
				{
				confirmAddGroup( req, out );
				return;
				}
			}
		catch ( BuildingServerException bsex )
			{
			out.println( "Technical problem creating page.<HR>" );
			out.println( bsex.toString() );
			}
		
		super.insert( req, out, command, insertname );
		}
		
	public void groupTable( Request req, PrintWriter out )
		throws ServletException, BuildingServerException, IOException
		{
		Enumeration enumeration = Group.findGroups( "resource_id = " + req.getResource().getResourceId() );
		Group group;

		Vector group_list = new Vector();
		while ( enumeration.hasMoreElements() )
			{
			group = (Group)enumeration.nextElement();
			if ( group.isLocalGroup() )
				continue;
			group_list.addElement( group );
			}
		
		
        //out.print( "<form method=post action=addgroup.html>" );
        //out.println( "<INPUT TYPE=SUBMIT VALUE=\"Add New Group\"></FORM>" );
		
		if ( group_list.size()==0 )
			{
			out.println( "<P>There are currently no groups here.</P>" );
			return;
			}

		enumeration = group_list.elements();
			
		out.println( "<TABLE CLASS=bs-table-opaque><TR>" );
		out.println( "<TD CLASS=bs-cell-special><strong>Name</strong></TD>" );
		out.println( "<TD CLASS=bs-cell-special><strong>Description</strong></TD>" );
		out.println( "<TD CLASS=bs-cell-special><strong>Membership</strong></TD></TR>" );
		
		while ( enumeration.hasMoreElements() )
			{
			group = (Group)enumeration.nextElement();
			out.print( "<TR><TD>" );
			out.print( group.getName() );
			out.print( "</TD><TD>" );
			out.print( group.getDescription() );
			out.print( "</TD>\n<TD>" );
            out.print( "<font size=2><form method=post ACTION=bs_template_accessgroup.html target=groupwindow>" );
            out.print( "<input type=hidden name=group_id value=" );
            out.print( group.getGroupId().toString() );
            out.print( "><INPUT TYPE=SUBMIT VALUE=\" Membership \" ONCLICK=\"grpwin()\"></FORM>" );
            out.println( "</font></td></TR>" );
			}

		out.println( "</TABLE>" );

		
		}
		
	public void confirmAddGroup( Request req, PrintWriter out )
		throws ServletException, BuildingServerException, IOException
		{
		if ( !req.getResource().checkPermission( Permission.EDIT ) )
			{
			out.println( "You don't have EDIT level permission here." );
			return;
			}
			
		String name, description;
		Group newgroup;

		
		name = req.getParameter( "name" );
		description = req.getParameter( "description" );
        
		
		newgroup = new Group();
		newgroup.setResourceId( req.getResource().getResourceId() );
		newgroup.setName( name );
		newgroup.setDescription( description );
		newgroup.setSpecialGroup( null );
		newgroup.save();
		
		out.println( "Confirmation: group created" );
		}
	}


