/*
 * Copyright 2004, 2005 John G. Wilson
 *
 * 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 uk.co.wilson.net.xmlrpc;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import org.xml.sax.AttributeList;
import org.xml.sax.SAXException;

import uk.co.wilson.net.xmlrpc.XMLRPCFailException;
import uk.co.wilson.xml.MinML;

public class XMLRPCMessageProcessor extends MinML {
  
  private static final String startResponse = ("<methodResponse>\n" +
                                               "\t<params>\n" +
                                               "\t\t<param>\n");
  private static final String endResponse = ("\n" +
                                             "\t\t</param>\n" +
                                             "\t</params>\n" +
                                             "</methodResponse>");
  private static final String startError = ("<methodResponse>\n" +
                                            "\t<fault>\n" +
                                            "\t\t<value>\n" +
                                            "\t\t\t<struct>\n" +
                                            "\t\t\t\t<member>\n" +
                                            "\t\t\t\t\t<name>faultCode</name>\n" +
                                            "\t\t\t\t\t<value><int>");
  private static final String middleError = ("</int></value>\n" +
                                             "\t\t\t\t</member>\n" +
                                             "\t\t\t\t<member>\n" +
                                             "\t\t\t\t\t<name>faultString</name>\n" +
                                             "\t\t\t\t\t<value><string>");
  private static final String endError = ("</string></value>\n" +
                                          "\t\t\t\t</member>\n" +
                                          "\t\t\t</struct>\n" +
                                          "\t\t</value>\n" +
                                          "\t</fault>\n" +
                                          "</methodResponse>\n");
	private static final byte[] translateTable = (
			//
			"\u0042\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
			//                    \t    \n                \r
			+ "\u0042\u0042\u0041\u0041\u0042\u0042\u0041\u0042"
			//
			+ "\u0042\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
			//
			+ "\u0042\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
			//        sp    !     "     #     $     %     &     '
			+ "\u0041\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
			//         (    )     *     +     ,     -     .     /
			+ "\u0042\u0042\u0042\u003E\u0042\u0042\u0042\u003F"
			//         0    1     2     3     4     5     6     7
			+ "\u0034\u0035\u0036\u0037\u0038\u0039\u003A\u003B"
			//         8    9     :     ;     <     =     >     ?
			+ "\u003C\u003D\u0042\u0042\u0042\u0040\u0042\u0042"
			//         @    A     B     C     D     E     F     G
			+ "\u0042\u0000\u0001\u0002\u0003\u0004\u0005\u0006"
			//         H    I   J K   L     M   N   O
			+ "\u0007\u0008\t\n\u000B\u000C\r\u000E"
			//         P    Q     R     S     T     U     V    W
			+ "\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016"
			//         X    Y     Z     [     \     ]     ^    _
			+ "\u0017\u0018\u0019\u0042\u0042\u0042\u0042\u0042"
			//         '    a     b     c     d     e     f     g
			+ "\u0042\u001A\u001B\u001C\u001D\u001E\u001F\u0020"
			//        h   i   j     k     l     m     n     o    p
			+ "\u0021\"\u0023\u0024\u0025\u0026\u0027\u0028"
			//        p     q     r     s     t     u     v     w
			+ "\u0029\u002A\u002B\u002C\u002D\u002E\u002F\u0030"
			//        x     y     z
			+ "\u0031\u0032\u0033").getBytes();
	
	protected interface Emitter {
		void emit(StringBuffer buffer, Object value) throws XMLRPCFailException;
	}
	
	protected final static Map elements = new HashMap();
	static {
		final char[] tTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();
		
		elements.put(Integer.class,
				new Emitter() {
					public void emit(final StringBuffer buffer, final Object integer) {
						buffer.append("<value><i4>").append(integer).append("</i4></value>");
					}
				});
		elements.put(Character.class, elements.get(Integer.class));
		elements.put(Byte.class, elements.get(Integer.class));
		elements.put(Short.class, elements.get(Integer.class));
		
		elements.put(Double.class,
				new Emitter() {
					public void emit(final StringBuffer buffer, final Object number) {
						buffer.append("<value><double>").append(number).append("</double></value>");
					}
				});
		elements.put(Float.class, elements.get(Double.class));
		elements.put(BigDecimal.class, elements.get(Double.class));
		
		elements.put(String.class,
				new Emitter() {
					public void emit(final StringBuffer buffer, final Object string) throws XMLRPCFailException {
						encodeString(buffer.append("<value><string>"), string.toString()).append("</string></value>");
					}
				});
		
		elements.put(Boolean.class,
				new Emitter() {
					public void emit(final StringBuffer buffer, final Object bool) {
						buffer.append("<value><boolean>").append((((Boolean)bool).booleanValue()) ? "1" : "0").append("</boolean></value>");
					}
				});
		
		elements.put(byte [].class,
				new Emitter() {
					public void emit(final StringBuffer buffer, final Object bytes) {
						int charCount = 0;
						final byte[] data = (byte[])bytes;
						final int numChars = ((data.length + 2) / 3) * 4;
						final int dLimit = (data.length / 3) * 3;
						
						buffer.ensureCapacity(numChars + 128 + (data.length / 54));
						buffer.append("<value><base64>\n");

						for (int dIndex = 0; dIndex != dLimit; dIndex += 3) {
							int d = ((data[dIndex] & 0XFF) << 16) |  ((data[dIndex + 1] & 0XFF) << 8) | (data[dIndex + 2] & 0XFF);

							buffer.append(tTable[d >> 18]);
							buffer.append(tTable[(d >> 12) & 0X3F]);
							buffer.append(tTable[(d >> 6) & 0X3F]);
							buffer.append(tTable[d & 0X3F]);

							if (++charCount == 18) {
								buffer.append('\n');
								charCount = 0;
							}
						}

						if (dLimit != data.length) {
							int d = (data[dLimit] & 0XFF) << 16;

							if (dLimit + 1 != data.length) {
								d |= (data[dLimit + 1] & 0XFF) << 8;
							}

							buffer.append(tTable[d >> 18]);
							buffer.append(tTable[(d >> 12) & 0X3F]);
							buffer.append((dLimit + 1 < data.length) ? tTable[(d >> 6) & 0X3F] : '=');
							buffer.append('=');
						}
						
						buffer.append("\n</base64></value>");
					}
				});
		
		elements.put(Date.class,
				new Emitter() {
					private final DateFormat dateTime = new SimpleDateFormat ("yyyyMMdd'T'HH:mm:ss");
					
					public synchronized void emit(final StringBuffer buffer, final Object date) {
						buffer.append("<value><dateTime.iso8601>").append(this.dateTime.format((Date)date)).append("</dateTime.iso8601></value>");
					}
				});
	}
  
  public static StringBuffer emitCall(final StringBuffer buffer, final String methodName, final Object[] params, final int numberOfparams) throws XMLRPCFailException {
    encodeString(buffer.append("<methodCall>\n\t<methodName>"), methodName).append("</methodName>\n\t<params>\n");

    for (int i = 0; i != numberOfparams; i++) {
      emit(buffer.append("\t\t<param>"), params[i]).append("</param>\n");
    }

    return buffer.append("\t</params>\n</methodCall>\n");
  }
  
  public static StringBuffer emitResult(final StringBuffer buffer, final Object result) throws XMLRPCFailException {
    buffer.append(startResponse);
    emit(buffer, result);
    buffer.append(endResponse);
    
    return buffer;
  }
  
  public static StringBuffer emitError(final StringBuffer buffer, final int codeValue, final String message) throws XMLRPCFailException {
    buffer.append(startError);
    emit(buffer, String.valueOf(codeValue));
    buffer.append(middleError);
    emit(buffer, message);
    buffer.append(endError);
    
    return buffer;
  }
  
	private static StringBuffer emit(final StringBuffer buffer, final Object param) throws XMLRPCFailException {
		if (param == null) {
			throw new XMLRPCFailException("an XML-RPC data value cannot be null", 0);
		}
		
		final Emitter emitter = (Emitter)elements.get(param.getClass());
		
		if (emitter == null) {
			if (param instanceof List) {
				final Iterator iterator = ((List)param).iterator();
				
				buffer.append("<value><array><data>");
				
				while (iterator.hasNext()) {
					emit(buffer, iterator.next());
				}
				
				buffer.append("</data></array></value>");
				
			} else if (param instanceof Map) {
				final Iterator iterator =((Map)param).entrySet().iterator();
				
				buffer.append("<value><struct>");
				
				while (iterator.hasNext()) {
				final Map.Entry entry = (Map.Entry)iterator.next();
				final Object name = entry.getKey();
				
					if (name == null) {
						throw new XMLRPCFailException("the name of a struct element cannot be null", 0);
					}
					
					emit(encodeString(buffer.append("<member><name>"), name.toString()).append("</name>"), entry.getValue()).append("</member>");
				}
				
				buffer.append("</struct></value>");
			} else {
        //
        // Work up the chain of classes to see if this is
        //  a subclass of a class we can handle
        //
			  Class superClass = param.getClass();
        
        while (true) {
        final Emitter superEmitter = (Emitter)elements.get(superClass);
        
          if (superEmitter != null) {
            superEmitter.emit(buffer, param);
            break;
          } else {
            if (superClass == Object.class) {
              throw new XMLRPCFailException(param.getClass() + " is not a supported XML-RPC data type", 0);
            } else  {
              superClass = superClass.getSuperclass();
            }
          }
        }
			}
		} else {
			emitter.emit(buffer, param);
		}
		
		return buffer;
	}
	
	public static StringBuffer encodeString(final StringBuffer buffer, final String string) throws XMLRPCFailException {
		for (int i = 0; i != string.length(); i++) {
			final char c = string.charAt(i);
			
			if (c >= 0X20 || c == 0X09 || c == 0X0A || c == 0X0D) {
				if (c == '>') {
					buffer.append("&gt;");
				} else if (c == '<') {
					buffer.append("&lt;");
				} else if (c == '&') {
					buffer.append("&amp;");
				} else if (c > 0xff) {
					if (c > 0XD800 && !(c >= 0XE000 && c < 0XFFFE)) 
						throw new XMLRPCFailException("Can't include character with value 0x"
											   		 + Integer.toHexString(c)
													 + " in a well formed XML document",
													 0);
					

					buffer.append("&#x").append(Integer.toHexString(c)).append(';');
				} else {
					buffer.append(c);
				}
			} else {
				throw new XMLRPCFailException("Can't include character with value 0x"
						               		 + Integer.toHexString(c)
											 + " in a well formed XML document",
											 0);
			}
		}
		
		return buffer;
	}
	
	/*
	 * A really cheap and cheerful XML-RPC reponse parser 
	 * It only really cares if the reponse contains a <param> or <fault>
	 * element. When the server is implemented this will be redone to be lots pickier.
	 */
	
	
	private Object params = null;
	private Object name = null;
	private String methodName = null;
	private Map struct = null;
	private List array = null;
	private Boolean inArray = Boolean.FALSE;
	private Stack aggregateStack = new Stack();
	private boolean gotValue = false;
	private final StringBuffer buffer = new StringBuffer();
	private final DateFormat dateTime = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
	private final DateFormat dateTime1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
	private final Boolean bools[] = {Boolean.FALSE, Boolean.TRUE};
  
  public void parseMessage(final String message) throws IOException, XMLRPCFailException { 
    try {
      parse(new StringReader(message));
    } catch (final XMLRPCFailException e) {
      throw e;
    } catch (final SAXException e) {
      throw new XMLRPCFailException("XML error in response from remote system: " + e.getMessage(), 0);
    }
  }
  
  public void parseMessage(final InputStream in) throws IOException, XMLRPCFailException { 
		try {
			parse(new InputStreamReader(in, "ISO-8859-1"));
		} catch (final XMLRPCFailException e) {
			throw e;
		} catch (final SAXException e) {
			throw new XMLRPCFailException("XML error in response from remote system: " + e.getMessage(), 0);
		}
	}
	
	public List getParams() {
		return (List)this.params;
	}
	
	public String getMethodname() {
		return this.methodName;
	}
	
	/* (non-Javadoc)
	 * @see org.xml.sax.DocumentHandler#startElement(java.lang.String, org.xml.sax.AttributeList)
	 */
	public void startElement(final String name, final AttributeList attributes) {
		if ("value".equals(name) || "name".equals(name) || "methodName".equals(name)) {
			this.buffer.setLength(0);
			this.gotValue = false;
			this.aggregateStack.push(this.inArray);
			this.inArray = Boolean.FALSE;
		} else if ("struct".equals(name)) {
			this.aggregateStack.push(this.struct);
			this.aggregateStack.push(this.name);
			this.struct = new HashMap();
		} else if ("array".equals(name) || "params".equals(name)) {
			this.aggregateStack.push(this.inArray);
			this.inArray = Boolean.TRUE;
			this.aggregateStack.push(this.array);
			this.array = new ArrayList();
		}
	}
	
	/* (non-Javadoc)
	 * @see org.xml.sax.DocumentHandler#characters(char[], int, int)
	 */
	public void characters(final char[] ch, final int start, final int length) {
		this.buffer.append(ch, start, length);
	}

	/* (non-Javadoc)
	 * @see org.xml.sax.DocumentHandler#endElement(java.lang.String)
	 */
	public void endElement(final String name) throws SAXException {
		if ("value".equals(name)) {
			if (!this.gotValue) {
				this.params = this.buffer.toString();
				this.gotValue = true;
			}
			
			this.inArray = (Boolean)this.aggregateStack.pop();
			
			if (this.inArray.booleanValue())
				this.array.add(this.params);
		} else if ("string".equals(name)) {
			this.params = this.buffer.toString();
			this.gotValue = true;
		} else if ("i4".equals(name) || "int".equals(name)) {
			this.params = new Integer(this.buffer.toString());
			this.gotValue = true;
		} else if ("boolean".equals(name)) {
			try {
				this.params = this.bools[Integer.parseInt(this.buffer.toString())];
			}
			catch (final RuntimeException e) {
				throw new XMLRPCFailException("bad Boolean value: " + this.buffer.toString(), 0);
			}
			
			this.gotValue = true;
		} else if ("dateTime.iso8601".equals(name)) {
			try {
				synchronized (this) {
					this.params = this.dateTime.parse(this.buffer.toString());
				}
			} catch (final ParseException e) {
				//
				// Some implementations produce funny formats 
				// Try an alternate format
				//
				try {
					synchronized (this) {
						this.params = this.dateTime1.parse(this.buffer.toString());
					}
				} catch (final ParseException e1) {
					throw new XMLRPCFailException(e.getMessage(), 0);	// throw the original exception
				}
			}
			this.gotValue = true;
		} else if ("base64".equals(name)) {
			int bytesIndex = 0;
			int byteShift = 4;
			int tmp = 0;
			boolean done = false;
			
			for (int i = 0; i != this.buffer.length(); i++) {
			final char c = this.buffer.charAt(i);
			final int sixBit = (c < 123) ? translateTable[c] : 66;

				if (sixBit < 64) {
					if (done) throw new XMLRPCFailException("= character not at end of base64 value", 0);
	
					tmp = (tmp << 6) | sixBit;
	
					if (byteShift-- != 4) {
						this.buffer.setCharAt(bytesIndex++, (char)((tmp >> (byteShift * 2)) & 0XFF));
					}
	
				} else if (sixBit == 64) {
	
					byteShift--;
					done = true;
	
				} else if (sixBit == 66) {
					// RFC 2045 says that I'm allowed to take the presence of 
					// these characters as evedence of data corruption
					// So I will
					throw new XMLRPCFailException("bad character in base64 value", 0);
				}

				if (byteShift == 0) byteShift = 4;
			}
			this.buffer.setLength(bytesIndex);
			try {
				this.params = this.buffer.toString().getBytes("ISO-8859-1");
			} catch (UnsupportedEncodingException e) {
				throw new XMLRPCFailException("Base 64 decode produced byte values > 255", 0);
			}
			this.gotValue = true;
		} else if ("double".equals(name)) {
			this.params = new java.math.BigDecimal(this.buffer.toString());
			this.gotValue = true;
		} else if ("name".equals(name)) {
			this.name = this.buffer.toString();
			this.inArray = (Boolean)this.aggregateStack.pop();
		} else if ("member".equals(name)) {
			this.struct.put(this.name, this.params);
		} else if ("struct".equals(name)) {
			this.params = this.struct;
			this.name = (String)this.aggregateStack.pop();
			this.struct = (Map)this.aggregateStack.pop();
		} else if ("array".equals(name) || "params".equals(name)) {
			this.params = this.array;
			this.array = (List)this.aggregateStack.pop();
			this.inArray = (Boolean)this.aggregateStack.pop();
		} else if ("methodName".equals(name)) {
			this.methodName = this.buffer.toString();
			this.inArray = (Boolean)this.aggregateStack.pop();
		} else if ("fault".equals(name)) {
		//
		// Some implementations return String fault codes rather than integer ones 
		// This code tries to deal gracefully with this
		//
			
		final Object faultCode = ((Map)this.params).get("faultCode");
		final Object faultString = ((Map)this.params).get("faultString");
		final int faultCodeValue;
		final String faultStringValue;
		
			if (faultCode instanceof Integer) {
				faultCodeValue = ((Integer)faultCode).intValue();
				faultStringValue = faultString.toString();
			} else {
				faultCodeValue = 0;
				faultStringValue = faultString.toString() + " : " + faultCode.toString();
			}
		
			throw new XMLRPCFailException(faultStringValue, faultCodeValue);
		}
	}
}