package org.apache.maven.doxia.module.twiki.parser;

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

import org.apache.maven.doxia.util.ByLineReaderSource;
import org.apache.maven.doxia.parser.ParseException;
import org.junit.Test;

import static junit.framework.TestCase.assertNotNull;
import static org.junit.Assert.*;

/**
 * Tests the {@link org.apache.maven.doxia.module.twiki.parser.ParagraphBlockParser}
 *
 * @author Juan F. Codagnone
 * @since Nov 1, 2005
 */
public class ParagraphTest
    extends AbstractBlockTestCase
{
    @Test
    public final void testMultiLines()
        throws ParseException
    {
        final String text =
            "" + "\n\n\n" + "para1 -> text1\n" + "para1 -> text2\n" + "\n" + "para2 -> text1\n"
                + "para2 -> text2\n" + "   \n   \n  " + "para2 -> text1\n" + "para2 -> text2\n";

        final ByLineReaderSource source = new ByLineReaderSource( new StringReader( text ) );
        final ParagraphBlockParser parser = paraParser;

        ParagraphBlock block;

        block = (ParagraphBlock) parser.visit( source.getNextLine(), source );
        assertNotNull( block );
        assertEquals( 1, block.getBlocks().length );
        assertEquals( "para1 -> text1 para1 -> text2", ( (TextBlock) block.getBlocks()[0] ).getText() );

        block = (ParagraphBlock) parser.visit( source.getNextLine(), source );
        assertNotNull( block );
        assertEquals( 1, block.getBlocks().length );
        assertEquals( "para2 -> text1 para2 -> text2", ( (TextBlock) block.getBlocks()[0] ).getText() );
    }

    @Test
    public final void testParagraphWithList()
        throws ParseException
    {
        final String text =
            "" + "Description text:\n" + "   * item1\n" + "   * item2\n"
                + "This is more text in the same paragraph\n" + "\n" + "Another paragraph";

        final ByLineReaderSource source = new ByLineReaderSource( new StringReader( text ) );

        ParagraphBlock block;

        block = (ParagraphBlock) paraParser.visit( source.getNextLine(), source );
        assertNotNull( block );
        final Block[] firstLevelChilds = block.getBlocks();
        final int numberOfChilds = 3;
        assertEquals( numberOfChilds, firstLevelChilds.length );
        assertEquals( TextBlock.class, firstLevelChilds[0].getClass() );
        assertEquals( UnorderedListBlock.class, firstLevelChilds[1].getClass() );
        assertEquals( TextBlock.class, firstLevelChilds[2].getClass() );

        final Block[] listChilds = ( (UnorderedListBlock) firstLevelChilds[1] ).getBlocks();
        assertEquals( 2, listChilds.length );
        assertEquals( 1, ( (ListItemBlock) listChilds[0] ).getBlocks().length );
        assertEquals( "item1", ( (TextBlock) ( (ListItemBlock) listChilds[0] ).getBlocks()[0] ).getText() );
        assertEquals( "item2", ( (TextBlock) ( (ListItemBlock) listChilds[1] ).getBlocks()[0] ).getText() );
    }

    /**
     * tests some valid weired lists
     *
     * @throws ParseException on error
     */
    @Test
    public final void testParagraphWithStartingList()
        throws ParseException
    {
        final String text =
            "" + "   * item1\n" + "   * item2\n" + "This is more text in the same paragraph\n" + "\n"
                + "Another paragraph";

        final ByLineReaderSource source = new ByLineReaderSource( new StringReader( text ) );

        ParagraphBlock block;

        block = (ParagraphBlock) paraParser.visit( source.getNextLine(), source );
        assertNotNull( block );
        final Block[] firstLevelChilds = block.getBlocks();
        assertEquals( 2, firstLevelChilds.length );
        assertEquals( UnorderedListBlock.class, firstLevelChilds[0].getClass() );
        assertEquals( TextBlock.class, firstLevelChilds[1].getClass() );

        final Block[] listChilds = ( (UnorderedListBlock) firstLevelChilds[0] ).getBlocks();
        assertEquals( 2, listChilds.length );
        assertEquals( 1, ( (ListItemBlock) listChilds[0] ).getBlocks().length );
        assertEquals( "item1", ( (TextBlock) ( (ListItemBlock) listChilds[0] ).getBlocks()[0] ).getText() );
        assertEquals( "item2", ( (TextBlock) ( (ListItemBlock) listChilds[1] ).getBlocks()[0] ).getText() );
    }

    @Test
    public final void testHorizontalRule()
        throws ParseException
    {
        Block block, expected;
        ByLineReaderSource source;

        assertTrue( hruleParser.accept( "---" ) );
        assertFalse( hruleParser.accept( "---+ asdas" ) );

        source = new ByLineReaderSource( new StringReader( "" ) );
        expected = new HorizontalRuleBlock();
        block = hruleParser.visit( "---", source );
        assertNull( source.getNextLine() );
        assertEquals( expected, block );

        source = new ByLineReaderSource( new StringReader( "" ) );
        expected = new HorizontalRuleBlock();
        block = hruleParser.visit( "--- Some text ---- And some more", source );
        assertEquals( expected, block );
        expected = new ParagraphBlock( new Block[] { new TextBlock( "Some text ---- And some more" ) } );
        block = paraParser.visit( source.getNextLine(), source );
        assertEquals( expected, block );
    }

    @Test
    public final void testHorizontalRuleAndParagraph()
        throws ParseException
    {
        Block[] blocks, expected;
        ByLineReaderSource source;

        source = new ByLineReaderSource( new StringReader( "" + "Some text\n" + "-----------\n" + "More text" ) );
        expected =
            new Block[] { new ParagraphBlock( new Block[] { new TextBlock( "Some text" ) } ),
                new HorizontalRuleBlock(), new ParagraphBlock( new Block[] { new TextBlock( "More text" ) } ) };
        blocks = twikiParser.parse( source ).toArray( new Block[] {} );
        assertArrayEquals( expected, blocks );
    }
}
