/*
 * ====================================================================
 *
 * Copyright 1999-2002 The Apache Software Foundation 
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

 
package org.apache.slide.webdav.logger;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;

import org.apache.slide.webdav.util.WebdavStatus;
import org.jdom.CDATA;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;

 
/**
 * This class writes the header, the command and the body of an HTML request
 * or response in an XML structure.
 *
 */


public class XMLTestCaseGenerator {
    

    /** The XML outputter */
    private XMLOutputter xmlOut = new XMLOutputter(org.jdom.output.Format.getPrettyFormat()); // indent: 2 spaces, newlines=true

    
    private XHttpServletRequestFacade request;
    private XHttpServletResponseFacade response;
    
    private Element root = new Element( "test" );
    private Document doc = new Document( root );
    
        
    /*
     * Name of the thread
     */
    private String threadName;
    
    public void setThreadName( String threadName ) {
        this.threadName = threadName;
    }
    public String getThreadName() {
        return threadName;
    }
    
        
    
    /*
     * Constructs an XMLTestCaseGenerator object.
     */
    public XMLTestCaseGenerator( XHttpServletRequestFacade request, XHttpServletResponseFacade response){
        this.request = request;
        this.response = response;
    }
    
    /*
     * this method writes the data as XML.
     */
    public String toString() {
        String result = "";
            
        root.addContent( printXMLstep() );
        try {
            result = xmlOut.outputString( doc.getRootElement().getChild("step") );
        } catch ( Exception e ) {
            e.printStackTrace();
        }
        return result;
    }

    /*
     * this method prints the XML step attribute.
     */
    private Element printXMLstep() {
        Element stepElem = new Element( "step" );
//      stepElem.setAttribute(new Attribute("executeIn", getThreadName()));
        stepElem.addContent( printXMLrequest() );
        stepElem.addContent( printXMLresponse() );
        return stepElem;
    }
    /*
     * this method prints the XML request attribute.
     */
    private Element printXMLrequest() {
        Element stepElem = new Element( "request" );
        stepElem.addContent( printXMLrequestCommand() );
        Iterator it = printXMLrequestHeaders();
        while ( it.hasNext() ) {
            stepElem.addContent( (Element)it.next() );
        }
        stepElem.addContent( printXMLrequestBody() );
        return stepElem;
    }
                                  
    /*
     * this method prints the XML request attribute.
     */
    private Element printXMLresponse() {
        Element respElem = new Element( "response" );
        respElem.addContent( printXMLresponseCommand() );
        Iterator it = printXMLresponseHeaders();
        while ( it.hasNext() ) {
            respElem.addContent( (Element)it.next() );
        }
        respElem.addContent( printXMLresponseBody() );
        return respElem;
    }
                                  
    /*
     * this method prints the XML request command attribute.
     */
    private Element printXMLrequestCommand() {
        Element reqComElem = new Element( "command" );
        reqComElem.addContent( request.getMethod() + " " + request.getRequestURI() + " " + getProtocol() );
        return reqComElem;
    }
                                  
                                  
    /*
     * this method prints the XML request header attributes.
     */
    private Iterator printXMLrequestHeaders() {
        Vector vector = new Vector();
        Enumeration e = request.getHeaderNames();
        if ( e != null ) {
            while ( e.hasMoreElements() ) {
                String headerName = (String)e.nextElement();
                String headerValue = request.getHeader(headerName);
                Element elem = new Element( "header" );
                elem.addContent( headerName + ": " + headerValue );
                vector.add( elem );
            }
        }
        return vector.iterator();
    }
                                  
    /*
     * this method prints the XML request body attribute.
     */
    private Element printXMLrequestBody(){
        Element bodyElem = new Element( "body" );
        try {
            bodyElem.addContent( new CDATA(request.getRequestBody()) );
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return bodyElem;
    }

    /*
     * this method prints the XML response command attribute.
     */
    private Element printXMLresponseCommand() {
        Element respComElem = new Element( "command" );
        respComElem.addContent(
            getProtocol() + " " +
            response.getStatus() + " " +
            WebdavStatus.getStatusText(response.getStatus()));
        return respComElem;
    }
        
    /*
     * Returns the protocol without a trailing CRLF
     */
    private String getProtocol() {
        String result = request.getProtocol();
        while (result.endsWith("\n")) {
            result = result.substring(0, result.length()-"\n".length()-1);
        }
        return result;
    }
                                  
    /*
     * this method prints the XML response header attributes.
     */
    private Iterator printXMLresponseHeaders() {
        Vector vector = new Vector();
        XResponseHeader respHeader;
        Enumeration e = response.getResponseHeaders();
        if ( e != null ) {
            while ( e.hasMoreElements() ) {
                Element elem = new Element( "header" );
                elem.addContent( ((XResponseHeader)e.nextElement()).toString() );
                vector.add( elem );
            }
        }
        return vector.iterator();
    }
                                  
    /*
     * this method prints the XML response body attribute.
     */
    private Element printXMLresponseBody() {
        Element bodyElem = new Element( "body" );
        try {
            bodyElem.addContent( new CDATA(response.getResponseBody()) );
        } catch ( IOException e ) {
            e.printStackTrace();
        }
        return bodyElem;
    }

}
