/*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (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.mozilla.org/MPL/>.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 * language governing rights and limitations under the License.
 * 
 * The Original Code is the Venice Web Communities System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.venice.servlets;

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.log4j.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.servlets.format.*;

public class SystemAdmin extends VeniceServlet
{
  /*--------------------------------------------------------------------------------
   * Static data members
   *--------------------------------------------------------------------------------
   */

  private static Category logger = Category.getInstance(SystemAdmin.class);

  /*--------------------------------------------------------------------------------
   * Internal functions
   *--------------------------------------------------------------------------------
   */

  private SystemAdminTop makeSystemAdminTop() throws ServletException
  {
    final String desired_name = "SystemAdminTop";
    MenuPanelCache cache = MenuPanelCache.getMenuPanelCache(getServletContext());

    if (!(cache.isCached(desired_name)))
    { // create a template and save it off
      SystemAdminTop template = new SystemAdminTop();
      cache.saveTemplate(template);

    } // end if

    // return a new copy
    return (SystemAdminTop)(cache.getNewMenuPanel(desired_name));

  } // end makeSystemAdminTop

  private AdminModifyUserDialog makeAdminModifyUserDialog() throws ServletException
  {
    final String desired_name = "AdminModifyUserDialog";
    DialogCache cache = DialogCache.getDialogCache(getServletContext());

    if (!(cache.isCached(desired_name)))
    { // create a template and save it off
      AdminModifyUserDialog template = new AdminModifyUserDialog();
      cache.saveTemplate(template);

    } // end if

    // return a new copy
    return (AdminModifyUserDialog)(cache.getNewDialog(desired_name));

  } // end makeAdminModifyUserDialog

  private EditGlobalPropertiesDialog makeGlobalPropertiesDialog(SecurityInfo sinf) throws ServletException
  {
    final String desired_name = "EditGlobalPropertiesDialog";
    DialogCache cache = DialogCache.getDialogCache(getServletContext());

    if (!(cache.isCached(desired_name)))
    { // create a template and save it off
      EditGlobalPropertiesDialog template = new EditGlobalPropertiesDialog(sinf);
      cache.saveTemplate(template);

    } // end if

    // return a new copy
    return (EditGlobalPropertiesDialog)(cache.getNewDialog(desired_name));

  } // end makeGlobalPropertiesDialog

  /*--------------------------------------------------------------------------------
   * Overrides from class HttpServlet
   *--------------------------------------------------------------------------------
   */

  public String getServletInfo()
  {
    String rc = "SystemAdmin servlet - Administrative functions for the entire system\n"
              + "Part of the Venice Web Communities System\n";
    return rc;

  } // end getServletInfo

  /*--------------------------------------------------------------------------------
   * Overrides from class VeniceServlet
   *--------------------------------------------------------------------------------
   */

  protected VeniceContent doVeniceGet(HttpServletRequest request, VeniceEngine engine,
				      UserContext user, RenderData rdat)
      throws ServletException, IOException, VeniceServletResult
  {
    // decide what to do based on the "cmd" parameter
    String cmd = getStandardCommandParam(request);
    if (logger.isDebugEnabled())
      logger.debug("SystemAdmin/doGet command value = " + cmd);

    if (cmd.equals("A"))
    { // "A" = View System Audit Records
      try
      { // get the list of audit records
	AdminOperations adm = user.getAdminInterface();
	int offset = 0;
	try
	{ // convert the offset parameter
	  String s_ofs = request.getParameter("ofs");
	  if (!StringUtil.isStringEmpty(s_ofs))
	    offset = Integer.parseInt(s_ofs);

	} // end try
	catch (NumberFormatException nfe)
	{ // if it's untranslatable, set it at 0
	  offset = 0;

	} // end catch

	// generate the lists
	List audit_list = adm.getAuditRecords(offset,engine.getNumAuditRecordsPerPage());
	int audit_count = adm.getAuditRecordCount();

	// return the audit viewer
	setMyLocation(request,"sysadmin?cmd=A&ofs=" + offset);
	return new AuditDataViewer(engine,audit_list,offset,audit_count,"System Audit Records",
				   "sysadmin?cmd=A&ofs=%");

      } // end try
      catch (AccessError ae)
      { // an access error generally means we're not an administrator
	return new ErrorBox("Access Error","You do not have permission to administer the system.",null);

      } // end catch
      catch (DataException de)
      { // error pulling the audit records
	return new ErrorBox("Database Error","Unable to retrieve audit records: " + de.getMessage(),
			    "sysadmin");

      } // end catch

    } // end if ("A" command)

    if (cmd.equals("UF"))
    { // "UF" = "User Find" - the initial screen of User Account Management
      if (!(user.hasAdminAccess()))
	return new ErrorBox("Access Error","You do not have permission to administer the system.",null);

      // prepare and load the display
      AdminFindUser afu = new AdminFindUser(engine);
      afu.loadGet();
      setMyLocation(request,"sysadmin?cmd=UF");
      return afu;

    } // end if ("UF" command)

    if (cmd.equals("UM"))
    { // "UM" = "User Modify" - the second screen of user account management
      try
      { // get the user to be modified
	AdminOperations adm = user.getAdminInterface();
	String s_uid = request.getParameter("uid");
	if (s_uid==null)
	  throw new ErrorBox(null,"User ID parameter not found.","sysadmin?cmd=UF");
	AdminUserContext admuser = adm.getUserContext(Integer.parseInt(s_uid));

	AdminModifyUserDialog dlg = makeAdminModifyUserDialog();
	dlg.setupDialog(adm,admuser);
	setMyLocation(request,"sysadmin?cmd=UM");
	return dlg;

      } // end try
      catch (AccessError ae)
      { // an access error generally means we're not an administrator
	return new ErrorBox("Access Error","You do not have permission to administer the system.",null);

      } // end catch
      catch (DataException de)
      { // error pulling the audit records
	return new ErrorBox("Database Error","Unable to retrieve user information: " + de.getMessage(),
			    "sysadmin?cmd=UF");

      } // end catch
      catch (NumberFormatException nfe)
      { // this is if we get a bogus UID
	return new ErrorBox(null,"Invalid user ID parameter.","sysadmin?cmd=UF");

      } // end catch

    } // end if ("UM" command)

    if (cmd.equals("G"))
    { // "G" = Edit Global Properties
      try
      { // get the global properties
	AdminOperations adm = user.getAdminInterface();
	EditGlobalPropertiesDialog dlg = makeGlobalPropertiesDialog(adm.getSecurityInfo());
	dlg.setupDialog(adm);
	setMyLocation(request,"sysadmin?cmd=G");
	return dlg;

      } // end try
      catch (AccessError ae)
      { // an access error generally means we're not an administrator
	return new ErrorBox("Access Error","You do not have permission to administer the system.",null);

      } // end catch

    } // end if

    // TODO: other command handling

    if (!(user.hasAdminAccess()))
      return new ErrorBox("Access Error","You do not have permission to administer the system.",null);

    setMyLocation(request,"sysadmin");
    return makeSystemAdminTop();

  } // end doVeniceGet

  protected VeniceContent doVenicePost(HttpServletRequest request, VeniceEngine engine,
				       UserContext user, RenderData rdat)
      throws ServletException, IOException, VeniceServletResult
  {
    // decide what to do based on the "cmd" parameter
    String cmd = getStandardCommandParam(request);
    if (logger.isDebugEnabled())
      logger.debug("SystemAdmin/doPost command value = " + cmd);

    if (cmd.equals("UF"))
    { // "UF" = "User Find" - the initial screen of User Account Management
      if (!(user.hasAdminAccess()))
	return new ErrorBox("Access Error","You do not have permission to administer the system.",null);

      try
      {	// prepare and load the display
	AdminFindUser afu = new AdminFindUser(engine);
	afu.loadPost(request);
	setMyLocation(request,"sysadmin?cmd=UF");
	return afu;

      } // end try
      catch (DataException de)
      { // catch a database error and return it
	return new ErrorBox("Database Error","Database error on find: " + de.getMessage(),"sysadmin?cmd=UF");

      } // end catch
      catch (ValidationException ve)
      { // there was a validation error
	return new ErrorBox("Find Error",ve.getMessage(),"sysadmin?cmd=UF");

      } // end catch

    } // end if ("UF" command)

    if (cmd.equals("UM"))
    { // "UM" = "User Modify" - the second screen of user account management
      try
      { // get the dialog box
	AdminModifyUserDialog dlg = makeAdminModifyUserDialog();

	if (dlg.isButtonClicked(request,"cancel"))
	  throw new RedirectResult("sysadmin?cmd=UF");  // we decided not to bother - go back

	if (dlg.isButtonClicked(request,"update"))
	{ // get the user to be modified
	  AdminOperations adm = user.getAdminInterface();
	  String s_uid = request.getParameter("uid");
	  if (s_uid==null)
	    throw new ErrorBox(null,"User ID parameter not found.","sysadmin?cmd=UF");
	  AdminUserContext admuser = adm.getUserContext(Integer.parseInt(s_uid));

	  dlg.loadValues(request);  // load field values

	  try
	  { // execute the dialog!
	    dlg.doDialog(admuser);
	    throw new RedirectResult("sysadmin?cmd=UF");

	  } // end try
	  catch (ValidationException ve)
	  { // this is a simple error
	    dlg.resetOnError(adm,admuser,ve.getMessage() + " Please try again.");
	    setMyLocation(request,"sysadmin?cmd=UM");
	    return dlg;

	  } // end catch

	} // end if
	else
	{ // the button must be wrong!
	  logger.error("no known button click on SystemAdmin.doPost, cmd=UF");
	  return new ErrorBox("Internal Error","Unknown command button pressed","sysadmin?cmd=UF");

	} // end else

      } // end try
      catch (AccessError ae)
      { // an access error generally means we're not an administrator
	return new ErrorBox("Access Error","You do not have permission to administer the system.",null);

      } // end catch
      catch (DataException de)
      { // error pulling the audit records
	return new ErrorBox("Database Error","Unable to retrieve user information: " + de.getMessage(),
			    "sysadmin?cmd=UF");

      } // end catch
      catch (NumberFormatException nfe)
      { // this is if we get a bogus UID
	return new ErrorBox(null,"Invalid user ID parameter.","sysadmin?cmd=UF");

      } // end catch

    } // end if ("UM" command)

    if (cmd.equals("G"))
    { // "G" - Edit Global Properties
      try
      { // get the dialog box
	EditGlobalPropertiesDialog dlg = makeGlobalPropertiesDialog(engine.getSecurityInfo());

	if (dlg.isButtonClicked(request,"cancel"))
	  throw new RedirectResult("sysadmin");  // we decided not to bother - go back

	if (dlg.isButtonClicked(request,"update"))
	{ // update the system properties
	  AdminOperations adm = user.getAdminInterface();
	  dlg.loadValues(request);

	  try
	  { // execute the dialog!
	    dlg.doDialog(adm);
	    throw new RedirectResult("sysadmin");

	  } // end try
	  catch (ValidationException ve)
	  { // validation error - retry the dialog
	    dlg.setErrorMessage(ve.getMessage() + " Please try again.");
	    setMyLocation(request,"sysadmin?cmd=G");
	    return dlg;

	  } // end catch

	} // end if
	else
	{ // the button must be wrong!
	  logger.error("no known button click on SystemAdmin.doPost, cmd=G");
	  return new ErrorBox("Internal Error","Unknown command button pressed","sysadmin?cmd=UF");

	} // end else

      } // end try
      catch (AccessError ae)
      { // an access error generally means we're not an administrator
	return new ErrorBox("Access Error","You do not have permission to administer the system.",null);

      } // end catch
      catch (DataException de)
      { // error pulling the audit records
	return new ErrorBox("Database Error","Unable to update global properties: " + de.getMessage(),
			    "sysadmin");

      } // end catch

    } // end if ("G" command)

    // TODO: other command handling

    if (!(user.hasAdminAccess()))
      return new ErrorBox("Access Error","You do not have permission to administer the system.",null);

    setMyLocation(request,"sysadmin");
    return makeSystemAdminTop();

  } // end doVenicePost

} // end class SystemAdmin
