/*
  Copyright (C) 2006 Helge Hess

  This file is part of JOPE.

  JOPE is free software; you can redistribute it and/or modify it under
  the terms of the GNU Lesser General Public License as published by the
  Free Software Foundation; either version 2, or (at your option) any
  later version.

  JOPE is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with JOPE; see the file COPYING.  If not, write to the
  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  02111-1307, USA.
*/

package org.opengroupware.jope.appserver.core;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/*
 * THREAD: a response is not synchronized and can only be used from one
 *         thread w/o additional locking.
 */
public class WOResponse extends WOMessage implements WOActionResults {
  
  protected static int initialBufferSize = 4096;

  protected WORequest request = null;
  protected int       status  = WOMessage.HTTP_STATUS_OK;
  
  public WOResponse(WORequest _rq) {
    super();
    this.init(_rq);
  }
  
  protected void init(WORequest _rq) {
    super.init(_rq != null ? _rq.httpVersion() : null,
               null /* headers  */,
               null /* contents */,
               null /* userInfo */);
  
    this.request = _rq; // TODO: do we need to know that?
  
    this.outputStream = new ByteArrayOutputStream(initialBufferSize);
    
    /* preconfigure for HTML */
    if (this.headers == null || !this.headers.containsKey("content-type"))
      this.setHeaderForKey("text/html; charset=iso-8859-1", "content-type");
  }
  
  /* accessors */
  
  public void setStatus(int _status) {
    this.status = _status;
  }
  public int status() {
    return this.status;
  }
  
  public WORequest request() {
    return this.request;
  }
  
  public void disableClientCaching() {
    // TODO: add expires header
    // TODO: maybe add some etag which changes always?
    // TODO: check whether those are correct
    this.setHeaderForKey("no-cache", "cache-control");
    this.setHeaderForKey("no-cache", "pragma");
  }
  
  /* WOActionResults */

  public WOResponse generateResponse() {
    return this;
  }
  
  /* streaming */
  
  public boolean enableStreaming() {
    // TODO: complete
    /* before streaming can be enabled, all HTTP headers need to be setup! */
    if (this.isStreaming())
      return true;
    
    OutputStream os = this.request != null ? this.request.outputStream() : null;
    if (os == null) {
      log.info("cannot enable streaming because the WORequest " +
               "has no output stream: " + this.request);
      return false;
    }
    
    // TODO: setup HTTP stuff on ServletResponse prior writing!
    
    /* write existing content to stream */
    
    byte[] lContent = this.content();
    this.outputStream = null;
    
    if (lContent != null && lContent.length > 0) {
      try {
        os.write(lContent);
      }
      catch (IOException e) {
        this.lastException = e;
        return false;
      }
    }
    
    /* configure new stream */
    
    this.outputStream = os;
    return true;
  }
}
