/*
 * Delivered to the U.S. Government in Accordance with Contract FA8650-10-C-7080.
 *
 * EXPORT CONTROLLED
 * ECCN#   EAR99
 * Warning: This document contains technical data which is controlled under the
 * Bureau of Industry & Security's Export Administration Regulations and may not be
 * exported or re-exported without authorization by the Bureau of Industry & Security.
 * Diversion contrary to US law is prohibited.
 *
 * (c) 2011 United Technologies Corp.
 * Developed with the sponsorship of the Defense Advanced Research Projects Agency (DARPA).
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this data,
 * including any software or models in source or binary form, as well as any drawings, 
 * specifications, and documentation (collectively "the Data"), to deal in the Data without 
 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Data, and to permit persons to whom the Data
 * is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Data.
 *
 * THE DATA IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS, SPONSORS, DEVELOPERS, CONTRIBUTORS, OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE DATA OR THE
 * USE OR OTHER DEALINGS IN THE DATA.
 */
package meta.rmi;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Collection;

import org.jdom.Attribute;
import org.jdom.Content;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;

/**
 * A META SOA Service Response
 */
public class ServiceResponse {
	public static final int SERVER_ERROR = 500;
	public static final String SERVER_ERROR_MSG = "Internal Server Error";
	public static final int BAD_REQUEST = 400;
	public static final String BAD_REQUEST_MSG = "The syntax of the request was not understood by the server. ";
	private Document doc;
	private int status;
	private String msg;
    
	public ServiceResponse(ServiceRequest req) {
		 doc = new Document(new Element("service-response"));
		 status = 0;
		 msg = "OK";
		 String name = req.getRequestName();
		 String id   = req.getRequestId();

		 Element root = doc.getRootElement();
		 if ( name != null) {
		 root.setAttribute("name",name);
		 }
		 if ( id != null) {
			 root.setAttribute("id",id); 
		 }
	}
	
	/**
	 * Constructor (when supplied the XML text of the service response
	 *
	 * @param xmltext String containing the service response object
	 * @throws IOException if error parsing the input
	 * @throws JDOMException if any XML formatting error
	 */
	public ServiceResponse(String xmltext) throws JDOMException, IOException {
    SAXBuilder builder = new SAXBuilder();
    doc                = builder.build(new ByteArrayInputStream(xmltext.getBytes()));
    Element response   = doc.getRootElement();
    if (! response.getName().equals("service-response"))
    	throw new IllegalArgumentException(String.format(
    			        "Cannot construct a %s with a %s element", 
    			        this.getClass().getSimpleName(),
    			        response.getName()));
    
    status = 0;
    msg    = "OK";
    Element child = response.getChild("status");
    if (child != null) {
    	Attribute code = child.getAttribute("code");
    	if (code != null) status = code.getIntValue();
    	msg = child.getTextTrim();
    }		
	}
	
	/**
	 * Record the status of the service request
	 */
	public void setStatus(int status) {
		this.status = status;
	}
	/**
	 * Record the status message
	 */
	public void setStatusMsg(String msg) {
		this.msg = msg;
	}
	/**
	 * Add a collection to the document
	 */
	public void addContent(Collection<?> c) {
		Element root = doc.getRootElement();
		root.addContent(c);
	}
	/**
	 * Add an element to the document
	 * @param c
	 */
	public void addContent(Content c) {
		Element root = doc.getRootElement();
		root.addContent(c);
	}
	/**
	 * Report the service response XML document
	 */
    public String getContent() {
    	Element e = new Element("status");
    	e.setAttribute("code", String.valueOf(status) );
    	e.setText(msg);
    	Element root = doc.getRootElement();
    	root.addContent(e);
    	XMLOutputter outp = new XMLOutputter();
    	return outp.outputString(doc); 
    }
    
    /**
     * Report the service status
     * @return The status code. 0 = OK
     */
    public int getStatus() {
    	return status;
    }
    
    /**
     * Report the service status message
     * @return The message. Useful when status != 0
     */
    public String getStatusMsg() {
    	return msg;
    }
    
    /**
     * Report the service response as XML
     * @return A clone of the root element
     */
    public Element getXmlContent() {
    	return (Element) doc.getRootElement().clone();
    }
}
