package org.apache.maven.shared.utils.xml;

/*
 * 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.
 */

import org.apache.maven.shared.utils.xml.pull.XmlPullParserException;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

import javax.annotation.Nonnull;
import javax.annotation.WillClose;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Kristian Rosenvold
 */
public class Xpp3DomBuilder
{
    private static final boolean DEFAULT_TRIM = true;

    /**
     * @param reader {@link Reader}
     * @return the built dom.
     * @throws XmlPullParserException in case of an error.
     */
    public static Xpp3Dom build( @WillClose @Nonnull Reader reader )
        throws XmlPullParserException
    {
        return build( reader, DEFAULT_TRIM );
    }

    /**
     * @param is {@link InputStream}
     * @param encoding The encoding.
     * @return the built dom.
     * @throws XmlPullParserException in case of an error.
     */
    public static Xpp3Dom build( @WillClose InputStream is, @Nonnull String encoding )
        throws XmlPullParserException
    {
        return build( is, encoding, DEFAULT_TRIM );
    }

    /**
     * @param is {@link InputStream}
     * @param encoding The encoding.
     * @param trim true/false.
     * @return the built dom.
     * @throws XmlPullParserException in case of an error.
     */
    public static Xpp3Dom build( @WillClose InputStream is, @Nonnull String encoding, boolean trim )
        throws XmlPullParserException
    {
        try
        {
            Reader reader = new InputStreamReader( is, encoding );
            return build( reader, trim );
        }
        catch ( UnsupportedEncodingException e )
        {
            throw new RuntimeException( e );
        }
    }

    /**
     * @param reader {@link Reader}
     * @param trim true/false.
     * @return the built dom.
     * @throws XmlPullParserException in case of an error.
     */
    public static Xpp3Dom build( @WillClose Reader reader, boolean trim )
        throws XmlPullParserException
    {
        try ( Reader r = reader )
        {
            DocHandler docHandler = parseSax( new InputSource( r ), trim );
            return docHandler.result;
        }
        catch ( final IOException e )
        {
            throw new XmlPullParserException( e );
        }
    }

    private static DocHandler parseSax( @Nonnull InputSource inputSource, boolean trim )
        throws XmlPullParserException
    {
        try
        {
            DocHandler ch = new DocHandler( trim );
            XMLReader parser = createXmlReader();
            parser.setContentHandler( ch );
            parser.parse( inputSource );
            return ch;
        }
        catch ( IOException e )
        {
            throw new XmlPullParserException( e );
        }
        catch ( SAXException e )
        {
            throw new XmlPullParserException( e );
        }
    }


    private static XMLReader createXmlReader()
        throws SAXException
    {
        XMLReader comSunXmlReader = instantiate( "com.sun.org.apache.xerces.internal.parsers.SAXParser" );
        if ( comSunXmlReader != null )
        {
            return comSunXmlReader;
        }

        String key = "org.xml.sax.driver";
        String oldParser = System.getProperty( key );
        System.clearProperty( key ); // There's a "slight" problem with this an parallel maven: It does not work ;)

        try
        {
            return org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
        }
        finally
        {
            if ( oldParser != null )
            {
                System.setProperty( key, oldParser );
            }
        }

    }

    private static XMLReader instantiate( String s )
    {
        try
        {
            Class<?> aClass = Thread.currentThread().getContextClassLoader().loadClass( s );
            return (XMLReader) aClass.newInstance();
        }
        catch ( ClassNotFoundException e )
        {
            return  null;
        }
        catch ( InstantiationException e )
        {
            return  null;
        }
        catch ( IllegalAccessException e )
        {
            return  null;
        }
    }


    private static class DocHandler
        extends DefaultHandler
    {
        private final List<Xpp3Dom> elemStack = new ArrayList<>();

        private final List<StringBuilder> values = new ArrayList<>();

        // Todo: Use these for something smart !
        private final List<SAXParseException> warnings = new ArrayList<>();

        private final List<SAXParseException> errors = new ArrayList<>();

        private final List<SAXParseException> fatals = new ArrayList<>();


        Xpp3Dom result = null;

        private final boolean trim;

        private boolean spacePreserve = false;

        DocHandler( boolean trim )
        {
            this.trim = trim;
        }

        @Override
        public void startElement( String uri, String localName, String qName, Attributes attributes )
            throws SAXException
        {
            spacePreserve = false;
            Xpp3Dom child = new Xpp3Dom( localName );

            attachToParent( child );
            pushOnStack( child );

            // Todo: Detecting tags that close immediately seem to be impossible in sax ?
            // http://stackoverflow.com/questions/12968390/detecting-self-closing-tags-in-sax
            values.add( new StringBuilder() );

            int size = attributes.getLength();
            for ( int i = 0; i < size; i++ )
            {
                String name = attributes.getQName( i );
                String value = attributes.getValue( i );
                child.setAttribute( name, value );
                spacePreserve = spacePreserve || ( "xml:space".equals( name ) && "preserve".equals( value ) );
            }
        }

        private boolean pushOnStack( Xpp3Dom child )
        {
            return elemStack.add( child );
        }

        private void attachToParent( Xpp3Dom child )
        {
            int depth = elemStack.size();
            if ( depth > 0 )
            {
                elemStack.get( depth - 1 ).addChild( child );
            }
        }

        @Override
        public void warning( SAXParseException e )
            throws SAXException
        {
            warnings.add( e );
        }

        @Override
        public void error( SAXParseException e )
            throws SAXException
        {
            errors.add( e );
        }

        @Override
        public void fatalError( SAXParseException e )
            throws SAXException
        {
            fatals.add( e );
        }

        private Xpp3Dom pop()
        {
            int depth = elemStack.size() - 1;
            return elemStack.remove( depth );
        }

        @Override
        public void endElement( String uri, String localName, String qName )
            throws SAXException
        {
            int depth = elemStack.size() - 1;

            Xpp3Dom element = pop();

            /* this Object could be null if it is a singleton tag */
            Object accumulatedValue = values.remove( depth );

            if ( element.getChildCount() == 0 )
            {
                if ( accumulatedValue == null )
                {
                    element.setValue( "" ); // null in xpp3dom, but we don't do that around here
                }
                else
                {
                    element.setValue( accumulatedValue.toString() );
                }
            }

            if ( depth == 0 )
            {
                result = element;
            }
        }

        @Override
        public void characters( char[] ch, int start, int length )
            throws SAXException
        {
            String text = new String( ch, start, length );
            appendToTopValue( ( trim && !spacePreserve ) ? text.trim() : text );
        }

        private void appendToTopValue( String toAppend )
        {
            // noinspection MismatchedQueryAndUpdateOfStringBuilder
            StringBuilder stringBuilder = values.get( values.size() - 1 );
            stringBuilder.append( toAppend );
        }
    }

}
