package org.apache.maven.doxia.module.xdoc;

/*
 * 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 java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.Reader;
import java.io.Writer;

import java.util.Iterator;
import java.util.regex.Pattern;

import org.apache.maven.doxia.parser.AbstractParserTest;
import org.apache.maven.doxia.parser.ParseException;
import org.apache.maven.doxia.parser.Parser;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
import org.apache.maven.doxia.sink.impl.SinkEventElement;
import org.apache.maven.doxia.sink.impl.SinkEventTestingSink;
import org.codehaus.plexus.util.IOUtil;

/**
 * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
 * @author <a href="mailto:evenisse@codehaus.org">Emmanuel Venisse</a>
 * @version $Id$
 * @since 1.0
 */
public class XdocParserTest
    extends AbstractParserTest
{
    private XdocParser parser;

    @Override
    protected void setUp()
        throws Exception
    {
        super.setUp();

        parser = lookup( Parser.ROLE, "xdoc" );

        // AbstractXmlParser.CachedFileEntityResolver downloads DTD/XSD files in ${java.io.tmpdir}
        // Be sure to delete them
        String tmpDir = System.getProperty( "java.io.tmpdir" );

        final Pattern xsdFilePattern = Pattern.compile( "(xdoc\\-.*|xml)\\.xsd" );

        File[] xsdFiles = new File( tmpDir ).listFiles( new FileFilter()
        {

            public boolean accept( File pathname )
            {
                return pathname.isFile() && xsdFilePattern.matcher( pathname.getName() ).matches();
            }
        } );

        for ( File xsdFile : xsdFiles )
        {
            xsdFile.delete();
        }

        /* FileUtils 3.0.10 is about 5-8 times slower than File.listFiles() + regexp */
//        String includes = "xdoc-*.xsd, xml.xsd";
//        List<File> tmpFiles = FileUtils.getFiles( new File( tmpDir ), includes, null, true );
//        for ( File tmpFile  : tmpFiles )
//        {
//            tmpFile.delete();
//        }
    }

    /** {@inheritDoc} */
    protected String outputExtension()
    {
        return "xml";
    }

    /** {@inheritDoc} */
    protected Parser createParser()
    {
        return parser;
    }

    /** @throws Exception  */
    public void testSnippetMacro()
        throws Exception
    {
        try( Writer output = getTestWriter( "macro" );
             Reader reader = getTestReader( "macro" ) )
        {
            Sink sink = new XdocSink( output );
            createParser().parse( reader, sink );
            sink.close();
        }

        File f = getTestFile( getBasedir(), outputBaseDir() + getOutputDir() + "macro.xml" );
        assertTrue( "The file " + f.getAbsolutePath() + " was not created", f.exists() );

        String content;
        try( Reader reader = new FileReader( f ) )
        {
            content = IOUtil.toString( reader );
        }

        assertTrue( content.contains( "&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;" ) );
    }

    public void testTocMacro()
        throws Exception
    {
        try( Writer output = getTestWriter( "toc" );
             Reader reader = getTestReader( "toc" ) )
        {
            Sink sink = new XdocSink( output );
            createParser().parse( reader, sink );
            sink.close();
        }

        File f = getTestFile( getBasedir(), outputBaseDir() + getOutputDir() + "toc.xml" );
        assertTrue( "The file " + f.getAbsolutePath() + " was not created", f.exists() );

        String content;
        try ( Reader reader = new FileReader( f ) )
        {
            content = IOUtil.toString( reader );
        }

        // No section, only subsection 1 and 2
        assertTrue( content.contains( "<a href=\"#Section_11\">Section 11</a>" ) );
        assertFalse( content.contains( "<a href=\"#Section_1211\">Section 1211</a>" ) );
    }

    private Iterator<SinkEventElement> parseText( String text )
        throws ParseException
    {
        SinkEventTestingSink sink = new SinkEventTestingSink();

        parser.parse( text, sink );

        return sink.getEventList().iterator();
    }

    public void testHeadEventsList()
        throws Exception
    {
        String text = "<document>"
                + "<properties><title>title</title>"
                + "<!-- Test comment: DOXIA-312 -->"
                + "<author email=\"a@b.c\">John Doe</author></properties>"
                + "<head>"
                + "<meta name=\"security\" content=\"low\"/>"
                + "<base href=\"http://maven.apache.org/\"/>"
                + "</head>"
                + "<body></body></document>";

        Iterator<SinkEventElement> it = parseText( text );

        assertStartsWith( it, "head", "title", "text", "title_", "comment", "author", "text", "author_" );

        SinkEventElement unknown = it.next();
        assertEquals( "unknown", unknown.getName() );
        assertEquals( "meta", unknown.getArgs()[0] );

        unknown = it.next();
        assertEquals( "unknown", unknown.getName() );
        assertEquals( "base", unknown.getArgs()[0] );

        assertEquals( it, "head_", "body", "body_" );

        // DOXIA-359
        text = "<document>"
                + "<properties><title>properties title</title></properties>"
                + "<head><title>head title</title></head>"
                + "<body></body></document>";

        it = parseText( text );

        assertStartsWith( it, "head", "title" );

        SinkEventElement title = it.next();
        assertEquals( "text", title.getName() );
        assertEquals( "properties title", title.getArgs()[0] );

        assertEquals( it, "title_", "head_", "body",  "body_" );
    }

    public void testDocumentBodyEventsList()
        throws Exception
    {
        String text = "<document><body></body></document>";

        Iterator<SinkEventElement> it = parseText( text );

        assertEquals( it, "body", "body_" );
    }

    public void testSectionEventsList()
        throws Exception
    {
        String text = "<section name=\"sec 1\"><subsection name=\"sub 1\"></subsection></section>";

        Iterator<SinkEventElement> it = parseText( text );

        assertEquals( it, "section1", "sectionTitle1", "text", "sectionTitle1_", "section2", "sectionTitle2", "text",
                      "sectionTitle2_", "section2_", "section1_" );
    }

    public void testSectionAttributes()
        throws Exception
    {
        // DOXIA-448
        String text = "<section name=\"section name\" class=\"foo\" id=\"bar\"></section>";

        Iterator<SinkEventElement> it = parseText( text );

        assertStartsWith( it, "anchor", "anchor_" );

        SinkEventElement next = it.next();
        assertEquals( "section1", next.getName() );
        SinkEventAttributeSet set = (SinkEventAttributeSet) next.getArgs()[0];
        assertEquals( 3, set.getAttributeCount() );
        assertTrue( set.containsAttribute( "name", "section name" ) );
        assertTrue( set.containsAttribute( "class", "foo" ) );
        assertTrue( set.containsAttribute( "id", "bar" ) );

        next = it.next();
        assertEquals( "sectionTitle1", next.getName() );
        assertNull( next.getArgs()[0] );

        assertEquals( it, "text", "sectionTitle1_", "section1_" );
    }

    public void testNestedSectionsEventsList()
        throws Exception
    {
        // DOXIA-241
        String text = "<section name=\"section\"><h6>h6</h6><subsection name=\"subsection\"></subsection></section>";

        Iterator<SinkEventElement> it = parseText( text );

        assertEquals( it, "section1", "sectionTitle1", "text", "sectionTitle1_", "section2", "section3", "section4",
                      "section5", "sectionTitle5", "text", "sectionTitle5_", "section5_", "section4_", "section3_",
                      "section2_", "section2", "sectionTitle2", "text", "sectionTitle2_", "section2_", "section1_" );
    }

    public void testSourceEventsList()
        throws Exception
    {
        String text = "<source><a href=\"what.html\">what</a></source>";

        Iterator<SinkEventElement> it = parseText( text );

        assertEquals( it, "verbatim", "link", "text", "link_", "verbatim_" );

        text = "<source><![CDATA[<a href=\"what.html\">what</a>]]></source>";
        it = parseText( text );

        assertEquals( it, "verbatim", "text", "verbatim_" );

        text = "<source><![CDATA[<source>what</source>]]></source>";
        it = parseText( text );

        assertEquals( it, "verbatim", "text", "verbatim_" );
    }

    public void testSourceContainingDTD()
        throws Exception
    {
        String text = "<source><![CDATA[" +
                          "<!DOCTYPE web-app PUBLIC " +
                          "\"-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN\"" +
                          " \"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd\">" +
                      "]]></source>";

        Iterator<SinkEventElement> it = parseText( text );

        assertEquals( it, "verbatim", "text", "verbatim_" );
    }

    public void testPreEOL()
        throws Exception
    {
        // test EOLs within <source>: the sink MUST receive a text event for the EOL
        String text = "<source><a href=\"what.html\">what</a>" + EOL
                + "<a href=\"what.html\">what</a></source>";

        Iterator<SinkEventElement> it = parseText( text );

        assertEquals( it, "verbatim", "link", "text", "link_", "text", "link", "text", "link_", "verbatim_" );
    }

    /**
     * Test section with ids.
     */
    public void testSectionIdAnchor()
        throws Exception
    {
        String text = "<section name=\"test\" id=\"test-id\">This is a test."
                + "<subsection name=\"sub-test\" id=\"sub-id\">Sub-section</subsection></section>";

        Iterator<SinkEventElement> it = parseText( text );

        assertEquals( it.next(), "anchor", "test-id" );

        assertStartsWith( it, "anchor_", "section1", "sectionTitle1", "text", "sectionTitle1_", "text" );

        assertEquals( it.next(), "anchor", "sub-id" );

        assertEquals( it, "anchor_", "section2", "sectionTitle2", "text", "sectionTitle2_", "text", "section2_",
                      "section1_" );
    }

    /**
     * Test script block.
     */
    public void testJavaScript()
        throws Exception
    {
        String text = "<script type=\"text/javascript\"><![CDATA[alert(\"Hello!\");]]></script>";

        Iterator<SinkEventElement> it = parseText( text );
        assertEquals( it, "unknown", "unknown", "unknown" );
    }

    /**
     * Test unknown tags.
     */
    public void testUnknown()
        throws Exception
    {
        String text = "<applet><param name=\"name\" value=\"value\"/><unknown/></applet>";

        Iterator<SinkEventElement> it = parseText( text );
        assertEquals( it, "unknown", "unknown", "unknown", "unknown", "unknown" );
    }

    /**
     * Test invalid macro tags.
     */
    public void testMacroExceptions()
    {
        SinkEventTestingSink sink = new SinkEventTestingSink();
        assertParseException( sink, "<macro/>" );
        assertParseException( sink, "<macro name=\"\"/>" );
        assertParseException( sink, "<macro name=\"name\"><param name=\"\" value=\"value\"/></macro>" );
        assertParseException( sink, "<macro name=\"name\"><param name=\"name\" value=\"\"/></macro>" );
        assertParseException( sink, "<macro name=\"name\"><param value=\"value\"/></macro>" );
        assertParseException( sink, "<macro name=\"name\"><param name=\"name\"/></macro>" );
        assertParseException( sink, "<macro name=\"unknown\"></macro>" );
    }

    private void assertParseException( Sink sink, String text )
    {
        try
        {
            parser.parse( text, sink );

            fail( "Should not be parseable: '" + text + "'" );
        }
        catch ( ParseException ex )
        {
            assertNotNull( ex );
        }
    }

    public void testEntities()
        throws Exception
    {
        final String text = "<!DOCTYPE test [<!ENTITY foo \"&#x159;\"><!ENTITY tritPos  \"&#x1d7ed;\">]>"
                + "<section name=\"&amp;&foo;&tritPos;\"><p>&amp;&foo;&tritPos;</p></section>";

        SinkEventTestingSink sink = new SinkEventTestingSink();

        parser.setValidate( false );
        parser.parse( text, sink );

        Iterator<SinkEventElement> it = sink.getEventList().iterator();

        assertStartsWith( it, "section1", "sectionTitle1" );

        assertEquals( it.next(), "text", "&\u0159\uD835\uDFED" );

        assertStartsWith( it, "sectionTitle1_", "paragraph" );

        assertEquals( it.next(), "text", "&" );

        assertEquals( it.next(), "text", "\u0159" );

        assertEquals( it.next(), "text", "\uD835\uDFED" );

        assertEquals( it, "paragraph_", "section1_" );
    }
    
    public void testStyleWithCData() throws Exception
    {
        // DOXIA-449
        final String text = "<style type=\"text/css\">\n" + 
        		"<![CDATA[\n" + 
        		"h2 {\n" + 
        		"font-size: 50px;\n" + 
        		"}\n" + 
        		"]]>\n" + 
        		"</style>"; 
        
        SinkEventTestingSink sink = new SinkEventTestingSink();

        parser.setValidate( false );
        parser.parse( text, sink );
        
        Iterator<SinkEventElement> it = sink.getEventList().iterator();
        SinkEventElement styleElm = it.next(); 
        assertEquals( "unknown", styleElm.getName() );
        assertEquals( "style", styleElm.getArgs()[0] );
        SinkEventElement cdataElm = it.next(); 
        assertEquals( "unknown", cdataElm.getName() );
        assertEquals( "CDATA", cdataElm.getArgs()[0] );
        SinkEventElement styleElm_ = it.next(); 
        assertEquals( "unknown", styleElm_.getName() );
        assertEquals( "style", styleElm_.getArgs()[0] );
        assertFalse( it.hasNext() );
    }
}
