/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 flex.messaging.io.amfx;

import flex.messaging.io.MessageDeserializer;
import flex.messaging.io.amf.ActionContext;
import flex.messaging.io.amf.ActionMessage;
import flex.messaging.io.amf.AmfTrace;
import flex.messaging.io.SerializationContext;
import flex.messaging.MessageException;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * SAX based AMFX Parser.
 */
public class AmfxMessageDeserializer extends DefaultHandler implements MessageDeserializer
{
    protected InputStream in;

    protected Locator locator;

    protected AmfxInput amfxIn;

    /*
     *  DEBUG LOGGING
     */
    protected AmfTrace debugTrace;
    protected boolean isDebug;

    /**
     * Constructor.
     * Create a new AmfxMessageDeserializer object
     *
     */
    public AmfxMessageDeserializer()
    {
    }

    /**
     * Establishes the context for reading in data from the given InputStream.
     * A null value can be passed for the trace parameter if a record of the
     * AMFX data should not be made.
     *
     * @param context SerializationContext object
     * @param in InputStream to process
     * @param trace AmfTrace object
     */
    public void initialize(SerializationContext context, InputStream in, AmfTrace trace)
    {
        amfxIn = new AmfxInput(context);
        this.in = in;

        debugTrace = trace;
        isDebug = debugTrace != null;

        if (debugTrace != null)
            amfxIn.setDebugTrace(debugTrace);
    }

    /**
     * Set the SerializationContext.
     *
     * @param context the SerializationContext object
     */
    public void setSerializationContext(SerializationContext context)
    {
        amfxIn = new AmfxInput(context);
    }

    /**
     * Read message from the ActionMessage and ActionContext.
     *
     * @param m current ActionMessage
     * @param context current ActionContext
     * @throws IOException when the read message process failed
     */
    public void readMessage(ActionMessage m, ActionContext context) throws IOException
    {
        if (isDebug)
            debugTrace.startRequest("Deserializing AMFX/HTTP request");

        amfxIn.reset();
        amfxIn.setDebugTrace(debugTrace);
        amfxIn.setActionMessage(m);

        parse(m);

        context.setVersion(m.getVersion());
    }

    /**
     * Read Object.
     * @return Object the object read from AmfxInput
     * @throws ClassNotFoundException, IOException when exceptions occurs in reading the object
     */
    public Object readObject() throws ClassNotFoundException, IOException
    {
        return amfxIn.readObject();
    }

    protected void parse(ActionMessage m)
    {
        try
        {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            factory.setValidating(false);
            factory.setNamespaceAware(true);
            SAXParser parser = factory.newSAXParser();
            parser.parse(in, this);
        }
        catch (MessageException ex)
        {
            clientMessageEncodingException(m, ex);
        }
        catch (SAXParseException e)
        {
            if (e.getException() != null)
            {
                clientMessageEncodingException(m, e.getException());
            }
            else
            {
                clientMessageEncodingException(m, e);
            }
        }
        catch (Exception ex)
        {
            clientMessageEncodingException(m, ex);
        }
    }

    /**
     * Implement {@link org.xml.sax.EntityResolver#resolveEntity(String, String)}.
     * 
     * AMFX does not need or use external entities, so disallow external entities
     * to prevent external entity injection attacks. 
     *
     * @param publicId the public Id
     * @param systemId the system Id
     * @return InputSource the InputSource after entity resolution
     * @throws SAXException, IOException if the process failed
     */
    public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException
    {
        throw new MessageException("External entities are not allowed");
    }
     
    protected void clientMessageEncodingException(ActionMessage m, Throwable t)
    {
        MessageException me;
        if (t instanceof MessageException)
        {
            me = (MessageException)t;
        }
        else
        {
            me = new MessageException("Error occurred parsing AMFX: " + t.getMessage());
        }

        me.setCode("Client.Message.Encoding");
        throw me;
    }

    /**
     * Start process of an Element.
     *
     * @param uri the URI of the element
     * @param localName the local name of the element
     * @param qName the qualify name of the element
     * @param attributes the Attributes in the element
     * @throws SAXException if the process failed
     */
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
    {
        try
        {
            String methodName = "start_" + localName;
            Method method = amfxIn.getClass().getMethod(methodName, attribArr);
            method.invoke(amfxIn, new Object[]{attributes});
        }
        catch (NoSuchMethodException e)
        {
            fatalError(new SAXParseException("Unknown type: " + qName, locator));
        }
        catch (IllegalAccessException e)
        {
            fatalError(new SAXParseException(e.getMessage(), locator, e));
        }
        catch (InvocationTargetException e)
        {
            Throwable t = e.getTargetException();
            if (t instanceof SAXException)
            {
                throw (SAXException)t;
            }
            else if (t instanceof Exception)
            {
                fatalError(new SAXParseException(t.getMessage(), locator, (Exception)t));
            }
            else
            {
                fatalError(new SAXParseException(e.getMessage(), locator, e));
            }
        }
    }

    /**
     * End process of an Element.
     *
     * @param uri the URI of the element
     * @param localName the local name of the element
     * @param qName the qualify name of the element
     * @throws SAXException if the process failed
     */
    public void endElement(String uri, String localName, String qName) throws SAXException
    {
        try
        {
            String methodName = "end_" + localName;
            Method method = amfxIn.getClass().getMethod(methodName, new Class[]{});
            method.invoke(amfxIn, new Object[]{});
        }
        catch (NoSuchMethodException e)
        {
            fatalError(new SAXParseException("Unfinished type: " + qName, locator));
        }
        catch (IllegalAccessException e)
        {
            fatalError(new SAXParseException(e.getMessage(), locator, e));
        }
        catch (InvocationTargetException e)
        {
            Throwable t = e.getTargetException();
            if (t instanceof SAXException)
            {
                throw (SAXException)t;
            }
            else if (t instanceof Error)
            {
                throw (Error)t;
            }
            else
            {
                fatalError(new SAXParseException(t.getMessage(), locator));
            }
        }
    }

    /**
     * Process a char array.
     *
     * @param ch the char array
     * @param start the start position in the char array
     * @param length the length of chars to process
     * @throws SAXException if the process failed
     */
    public void characters(char ch[], int start, int length) throws SAXException
    {
        String chars = new String(ch, start, length);
        if (chars.length() > 0)
        {
            amfxIn.text(chars);
        }
    }

    /**
     * Set the DocumentLocator object.
     *
     * @param l the DocumentLocator object
     */
    public void setDocumentLocator(Locator l)
    {
        locator = l;
    }


    /**
     * Process Error of a SAXParseException.
     *
     * @param exception SAXParseException
     * @throws SAXException rethrow the SAXException
     */
    public void error(SAXParseException exception) throws SAXException
    {
        throw new MessageException(exception.getMessage());
    }

    /**
     * Process FatalError of a SAXParseException.
     *
     * @param exception SAXParseException
     * @throws SAXException rethrow the SAXException
     */
    public void fatalError(SAXParseException exception) throws SAXException
    {
        if ((exception.getException() != null) && (exception.getException() instanceof MessageException))
            throw (MessageException)exception.getException();
        throw new MessageException(exception.getMessage());
    }

    /**
     * Process warning of a SAXParseException.
     *
     * @param exception SAXParseException
     * @throws SAXException rethrow the SAXException
     */
    public void warning(SAXParseException exception) throws SAXException
    {
        throw new MessageException(exception.getMessage());
    }

    private static Class[] attribArr = new Class[]{Attributes.class};
}
