/*
 * 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) 2002 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.dynamo.security;

import java.text.*;
import java.util.*;
import org.apache.log4j.Logger;
import com.silverwrist.dynamo.db.NamespaceCache;
import com.silverwrist.dynamo.except.*;
import com.silverwrist.dynamo.iface.*;
import com.silverwrist.dynamo.util.*;

class WriteAuditRecord implements AuditRecordCompose
{
  /*--------------------------------------------------------------------------------
   * Static data members
   *--------------------------------------------------------------------------------
   */

  private static Logger logger = Logger.getLogger(WriteAuditRecord.class);
  private static Logger audit_backup = Logger.getLogger("AUDIT");

  private static DateFormat AUDIT_FMT = DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.SHORT);

  /*--------------------------------------------------------------------------------
   * Attributes
   *--------------------------------------------------------------------------------
   */

  private AuditWriteOps m_ops;
  private NamespaceCache m_ns_cache;
  private String m_ip;
  private DynamoUser m_user;
  private int m_subid;
  private String m_event_namespace;
  private String m_event_name;
  private Object[] m_props = new Object[8];

  /*--------------------------------------------------------------------------------
   * Constructor
   *--------------------------------------------------------------------------------
   */

  WriteAuditRecord(AuditWriteOps ops, NamespaceCache ns_cache, String ip, DynamoUser user, int subid,
		   String event_namespace, String event_name)
  {
    m_ops = ops;
    m_ns_cache = ns_cache;
    m_ip = ip;
    m_user = user;
    m_subid = subid;
    m_event_namespace = event_namespace;
    m_event_name = event_name;
    for (int i=0; i<m_props.length; i++)
      m_props[i] = null;

  } // end constructor

  /*--------------------------------------------------------------------------------
   * Implementations from interface AuditRecord
   *--------------------------------------------------------------------------------
   */

  public long getRecordNum()
  {
    return -1;  // dummied out at compose time

  } // end getRecordNum

  public java.util.Date getTimestamp()
  {
    return null;  // dummied out at compose time

  } // end getTimestamp

  public String getEventNamespace()
  {
    return m_event_namespace;

  } // end getEventNamespace

  public String getEventName()
  {
    return m_event_name;

  } // end getEventName

  public DynamoUser getUser()
  {
    return m_user;

  } // end getUser

  public int getSubID()
  {
    return m_subid;

  } // end getSubID

  public String getIPAddress()
  {
    return m_ip;

  } // end getIPAddress

  public Object getProperty(int index)
  {
    if ((index<0) || (index>=m_props.length))
      throw new IndexOutOfBoundsException("invalid property index");
    return m_props[index];

  } // end getProperty
  
  /*--------------------------------------------------------------------------------
   * Implementations from interface AuditRecordCompose
   *--------------------------------------------------------------------------------
   */

  public void setProperty(int index, Object value)
  {
    if ((index<0) || (index>=m_props.length))
      throw new IndexOutOfBoundsException("invalid property index");
    m_props[index] = value;

  } // end setProperty

  public void write()
  {
    java.util.Date timestamp = new java.util.Date();  // spike the timestamp
    if (audit_backup.isInfoEnabled())
    { // write it all out to the backup event log, just in case the database write fails
      audit_backup.info("Event: " + m_event_namespace + "::" + m_event_name + " at "
			+ AUDIT_FMT.format(timestamp));
      if (m_user!=null)
      { // if user is null, subid is 0, so omit this line entirely
	if (m_subid==0)
	  audit_backup.info("    User " + m_user.getName() + " (" + m_user.getUID() + ") [" + m_ip + "]");
	else
	  audit_backup.info("    User " + m_user.getName() + " (" + m_user.getUID() + ") [" + m_ip
			    + "], subid = " + m_subid);

      } // end if
      for (int i=0; i<m_props.length; i++)
	if (m_props[i]!=null)
	  audit_backup.info("    Property[" + i + "] = " + m_props[i].toString());

    } // end if

    try
    { // translate the parameters to write out
      PropertyKey pkey = new PropertyKey(m_ns_cache.namespaceNameToId(m_event_namespace),m_event_name);
      m_ops.writeAuditRecord(pkey,timestamp,((m_user==null) ? 0 : m_user.getUID()),m_subid,m_ip,m_props);

    } // end try
    catch (DatabaseException e)
    { // log this exception to the regular logfile and continue
      logger.error("Failed to write audit record for " + m_event_namespace + "::" + m_event_name + " at "
		   + AUDIT_FMT.format(timestamp),e);

    } // end catch

  } // end write

} // end class WriteAuditRecord
