// JigsawHttpServletReponse.java
// $Id: JigsawHttpServletResponse.java,v 1.4 1997/01/24 12:03:09 abaird Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html

package w3c.jigsaw.servlet;

import java.io.*;
import java.servlet.*;
import java.servlet.http.*;
import java.net.*;

import w3c.www.mime.*;
import w3c.www.http.*;
import w3c.jigsaw.http.*;

/**
 *  @author Alexandre Rafalovitch <alex@access.com.au>
 *  @author Anselm Baird-Smith <abaird@w3.org>
 */

public class JigsawHttpServletResponse implements HttpServletResponse 
{
    private final static int STATE_INITIAL = 0;
    private final static int STATE_HEADERS_DONE = 1;
    private final static int STATE_ALL_DONE = 2;
    
    int   state = STATE_INITIAL;
    Reply reply = null;
    Request request = null;
    JigsawServletOutputStream out  = null;
    DataOutputStream          dout = null;

    private final void checkState(int state) {
	if ( this.state != state )
	    throw new RuntimeException("Invalid state: "+this.state);
    }

    // Setup the DataOutputStream (for reply emitting) and ServletOutputStream

    private synchronized final void computeOutputStream() {
	if ( out == null ) {
	    dout = new DataOutputStream(request.getClient().getOutputStream());
	    out  = new JigsawServletOutputStream(this, dout);
	}
    }

    protected final void emitHeaders() {
	if ( state == STATE_HEADERS_DONE ) {
	    return;
	} else {
	    checkState(STATE_INITIAL);
	}
	state = STATE_HEADERS_DONE;
	// Emit the reply itself:
	try {
	    computeOutputStream();
	    reply.emit(out);
	    reply.setStatus(HTTP.DONE);
	} catch (IOException ex) {
	    // Again in deeep trouble here !
	    ex.printStackTrace();
	}
    }

    JigsawHttpServletResponse(Request request, Reply reply)
    {
	this.request = request;
	this.reply   = reply;
	// FIXME Remove this once Servlets Keep-Alive is cleared out:
	reply.setKeepConnection(false);
    }
    
    public void setContentLength(int i)
    {
	checkState(STATE_INITIAL);
	reply.setContentLength(i);
    }
    
    public void setContentType(String spec)
    {
	checkState(STATE_INITIAL);
	try {
	    MimeType type= new MimeType(spec);
	    reply.setContentType(type);
	} catch(MimeTypeFormatException ex) {
	    // FIXME what should I do?
	}
    }
    
    public ServletOutputStream getOutputStream()
    {
	computeOutputStream();
	return out;
    }
    
    public void setStatus(int i, String reason)
    {
	checkState(STATE_INITIAL);
	reply.setStatus(i);
	reply.setReason(reason);
    }
    
    public void setStatus(int i)
    {
	setStatus(i, reply.getStandardReason(i));
    }
    
    public void setHeader(String name, String value)
    {
	checkState(STATE_INITIAL);
	reply.setValue(name, value);
    }
    
    public void setIntHeader(String name, int value)
    {
	setHeader(name, String.valueOf(value));
    }
    
    public void setDateHeader(String name, long date)
    {
	// FIX
	// I see no way to convert this into proper 
	// http type date string. Leave it to Jigsaw?
	setHeader(name, String.valueOf(date));
    }
    
    public void unsetHeader(String name)
    {
	setHeader(name, null);
    }
    
    public void sendError(int i, String msg)
        throws IOException
    {
	setStatus(i);
	reply.setContent(msg);
	state = STATE_ALL_DONE;
    }
    
    public void sendError(int i)
        throws IOException
    {
	setStatus(i);
	reply.setContent(reply.getStandardReason(i));
	state = STATE_ALL_DONE;
    }
    
    public void sendRedirect(String url)
        throws IOException
    {
	URL loc = null;
	try {
	    loc = new URL(request.getURL(), url);
	    setStatus(SC_MOVED_TEMPORARILY);
	    reply.setLocation(loc);
	    state = STATE_ALL_DONE;
	} catch (Exception ex) {
	    ex.printStackTrace();
	}
    }
}
