/*
** Luxor - XML User Interface Language (XUL) Toolkit
** Copyright (c) 2001, 2002 by Gerald Bauer
**
** This program is free software.
**
** You may redistribute it and/or modify it under the terms of the GNU
** General Public License as published by the Free Software Foundation.
** Version 2 of the license should be included with this distribution in
** the file LICENSE, as well as License.html. If the license is not
** included with this distribution, you may find a copy at the FSF web
** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
**
** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
** REDISTRIBUTION OF THIS SOFTWARE.
**
*/

package luxor.http;

import java.io.*;
import java.util.*;
import javax.swing.event.*;
import luxor.constant.*;
import luxor.event.*;

public class RequestResponseInfo
{

   private ArrayList _error = new ArrayList();
   private EventListenerList _listener = new EventListenerList();

   private RequestInfo _requestInfo;
   private int _responseCode = -1;
   private long _responseContentLength = -1;
   // todo: add client ip/dns
   private Date _timestamp;

   public RequestResponseInfo()
   {
      _timestamp = new Date();
   }

   public void setRequestInfo( RequestInfo requestInfo )
   {
      _requestInfo = requestInfo;
   }

   public void setResponseCode( int responseCode )
   {
      _responseCode = responseCode;
   }

   public void setResponseContentLength( long responseContentLength )
   {
      _responseContentLength = responseContentLength;
      fireUpdateSize( _responseContentLength );
      // todo: pass in respone object instead of size
   }

   public void setResponseError( Exception ex )
   {
      fireError( ex );
      // todo: pass in respone object instead of size
      // todo: set status to error
   }

   public void setResponseStatus( int status )
   {
      fireUpdateStatus( status );
      // todo: pass in respone object instead of size
   }

   public void setResponseTransferredSize( long size )
   {
      fireUpdateTransferredSize( size );
      // todo: pass in respone object instead of size
   }

   public String getLogString()
   {
      StringBuffer buf = new StringBuffer();

      buf.append( "[" + _timestamp + "]" );
      buf.append( " " + _requestInfo.getRequestLine() );

      String userAgent = _requestInfo.getUserAgentHeader();
      String referer = _requestInfo.getRefererHeader();
      String host = _requestInfo.getHostHeader();

      if( userAgent == null )
         userAgent = "";
      if( referer == null )
         referer = "";
      if( host == null )
         host = "";

      buf.append( " - " + userAgent );
      buf.append( " - " + referer );
      buf.append( " - " + host );

      buf.append( " - " + _responseCode );
      buf.append( " " + _responseContentLength );

      return buf.toString();
   }

   public RequestInfo getRequestInfo()
   {
      return _requestInfo;
   }

   /**
    *  multi line log string
    */
   public String getVerboseLogString()
   {
      StringBuffer buf = new StringBuffer();

      buf.append( _requestInfo.getRequestLine() + "\r\n" );

      Iterator it = _requestInfo.getHeaders().entrySet().iterator();
      while( it.hasNext() )
      {
         Map.Entry header = ( Map.Entry ) it.next();
         String key = ( String ) header.getKey();
         String value = ( String ) header.getValue();

         buf.append( key + ": " + value + "\r\n" );
      }

      Iterator errorIt = _error.iterator();
      while( errorIt.hasNext() )
      {
         Exception ex = ( Exception ) errorIt.next();

         buf.append( "*** error: " + ex.toString() );

         StringWriter stackTraceBuf = new StringWriter();
         PrintWriter stackTraceOut = new PrintWriter( stackTraceBuf );
         ex.printStackTrace( stackTraceOut );

         buf.append( stackTraceBuf.toString() );
         stackTraceOut.close();
      }

      buf.append( "========== ========== ========== ========== ==========\r\n" );

      return buf.toString();
   }

   public void addError( Exception ex )
   {
      _error.add( ex );
   }


   public void addResponeListener( ResponseListener l )
   {
      _listener.add( ResponseListener.class, l );
   }

   public void removeResponseListener( ResponseListener l )
   {
      _listener.remove( ResponseListener.class, l );
   }

   protected void fireError( Exception ex )
   {
      ResponseListener l[] = ( ResponseListener[] ) _listener.getListeners( ResponseListener.class );
      for( int i = 0; i < l.length; i++ )
         l[i].error( ex );
   }

   protected void fireUpdateSize( long size )
   {
      ResponseListener l[] = ( ResponseListener[] ) _listener.getListeners( ResponseListener.class );
      for( int i = 0; i < l.length; i++ )
         l[i].updateSize( size );
   }

   protected void fireUpdateStatus( int status )
   {
      ResponseListener l[] = ( ResponseListener[] ) _listener.getListeners( ResponseListener.class );
      for( int i = 0; i < l.length; i++ )
         l[i].updateStatus( status );
   }

   protected void fireUpdateTransferredSize( long size )
   {
      ResponseListener l[] = ( ResponseListener[] ) _listener.getListeners( ResponseListener.class );
      for( int i = 0; i < l.length; i++ )
         l[i].updateTransferredSize( size );
   }
}