/*
 * 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 org.netbeans.modules.php.doctrine2.annotations.odm.parser;

import java.util.Map;
import org.netbeans.junit.NbTestCase;
import org.netbeans.modules.csl.api.OffsetRange;
import org.netbeans.modules.php.spi.annotation.AnnotationLineParser;
import org.netbeans.modules.php.spi.annotation.AnnotationParsedLine;

/**
 *
 * @author Ondrej Brejla <obrejla@netbeans.org>
 */
public class DocumentLineParserTest extends NbTestCase {
    private ComplexAnnotationLineParser parser;

    public DocumentLineParserTest(String name) {
        super(name);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        this.parser = new ComplexAnnotationLineParser();
    }

    public void testIsAnnotationParser() throws Exception {
        assertTrue(parser instanceof AnnotationLineParser);
    }

    public void testReturnValueIsDocumentParsedLine_01() throws Exception {
        assertTrue(parser.parse("Document") instanceof AnnotationParsedLine.ParsedLine);
    }

    public void testReturnValueIsDocumentParsedLine_02() throws Exception {
        assertTrue(parser.parse("Annotations\\Document") instanceof AnnotationParsedLine.ParsedLine);
    }

    public void testReturnValueIsDocumentParsedLine_03() throws Exception {
        assertTrue(parser.parse("\\Foo\\Bar\\Document") instanceof AnnotationParsedLine.ParsedLine);
    }

    public void testReturnValueIsDocumentParsedLine_04() throws Exception {
        assertTrue(parser.parse("Annotations\\Document(repositoryClass=\"MyProject\\UserRepository\", indexes={@Index(keys={\"username\"=\"desc\"}, db=\"documents\", collection=\"users\", options={\"unique\"=true})}, requireIndexes=true)") instanceof AnnotationParsedLine.ParsedLine);
    }

    public void testReturnValueIsNull() throws Exception {
        assertNull(parser.parse("Documents"));
    }

    public void testValidUseCase_01() throws Exception {
        AnnotationParsedLine parsedLine = parser.parse("Document");
        assertEquals("Document", parsedLine.getName());
        assertEquals("", parsedLine.getDescription());
        Map<OffsetRange, String> types = parsedLine.getTypes();
        assertNotNull(types);
        assertEquals(1, types.size());
        String type1 = types.get(new OffsetRange(0, 8));
        assertEquals("Document", type1);
    }

    public void testValidUseCase_02() throws Exception {
        AnnotationParsedLine parsedLine = parser.parse("Document   ");
        assertEquals("Document", parsedLine.getName());
        assertEquals("", parsedLine.getDescription());
        Map<OffsetRange, String> types = parsedLine.getTypes();
        assertNotNull(types);
        assertEquals(1, types.size());
        String type1 = types.get(new OffsetRange(0, 8));
        assertEquals("Document", type1);
    }

    public void testValidUseCase_03() throws Exception {
        AnnotationParsedLine parsedLine = parser.parse("Document\t\t  ");
        assertEquals("Document", parsedLine.getName());
        assertEquals("", parsedLine.getDescription());
        Map<OffsetRange, String> types = parsedLine.getTypes();
        assertNotNull(types);
        assertEquals(1, types.size());
        String type1 = types.get(new OffsetRange(0, 8));
        assertEquals("Document", type1);
    }

    public void testValidUseCase_04() throws Exception {
        AnnotationParsedLine parsedLine = parser.parse("Document(repositoryClass=\"MyProject\\UserRepository\", indexes={@Index(keys={\"username\"=\"desc\"}, db=\"documents\", collection=\"users\", options={\"unique\"=true})}, requireIndexes=true)");
        assertEquals("Document", parsedLine.getName());
        assertEquals("(repositoryClass=\"MyProject\\UserRepository\", indexes={@Index(keys={\"username\"=\"desc\"}, db=\"documents\", collection=\"users\", options={\"unique\"=true})}, requireIndexes=true)", parsedLine.getDescription());
        Map<OffsetRange, String> types = parsedLine.getTypes();
        assertNotNull(types);
        assertEquals(3, types.size());
        String type1 = types.get(new OffsetRange(0, 8));
        assertEquals("Document", type1);
        String type2 = types.get(new OffsetRange(26, 50));
        assertEquals("MyProject\\UserRepository", type2);
        String type3 = types.get(new OffsetRange(63, 68));
        assertEquals("Index", type3);
    }

    public void testValidUseCase_05() throws Exception {
        AnnotationParsedLine parsedLine = parser.parse("Annotations\\Document(repositoryClass=\"MyProject\\UserRepository\", indexes={@Index(keys={\"username\"=\"desc\"}, db=\"documents\", collection=\"users\", options={\"unique\"=true})}, requireIndexes=true)  \t");
        assertEquals("Document", parsedLine.getName());
        assertEquals("(repositoryClass=\"MyProject\\UserRepository\", indexes={@Index(keys={\"username\"=\"desc\"}, db=\"documents\", collection=\"users\", options={\"unique\"=true})}, requireIndexes=true)", parsedLine.getDescription());
        Map<OffsetRange, String> types = parsedLine.getTypes();
        assertNotNull(types);
        assertEquals(3, types.size());
        String type1 = types.get(new OffsetRange(0, 20));
        assertEquals("Annotations\\Document", type1);
        String type2 = types.get(new OffsetRange(38, 62));
        assertEquals("MyProject\\UserRepository", type2);
        String type3 = types.get(new OffsetRange(75, 80));
        assertEquals("Index", type3);
    }

    public void testValidUseCase_06() throws Exception {
        AnnotationParsedLine parsedLine = parser.parse("\\Foo\\Bar\\Document(repositoryClass=\"MyProject\\UserRepository\", indexes={@Index(keys={\"username\"=\"desc\"}, db=\"documents\", collection=\"users\", options={\"unique\"=true})}, requireIndexes=true)  \t");
        assertEquals("Document", parsedLine.getName());
        assertEquals("(repositoryClass=\"MyProject\\UserRepository\", indexes={@Index(keys={\"username\"=\"desc\"}, db=\"documents\", collection=\"users\", options={\"unique\"=true})}, requireIndexes=true)", parsedLine.getDescription());
        Map<OffsetRange, String> types = parsedLine.getTypes();
        assertNotNull(types);
        assertEquals(3, types.size());
        String type1 = types.get(new OffsetRange(0, 17));
        assertEquals("\\Foo\\Bar\\Document", type1);
        String type2 = types.get(new OffsetRange(35, 59));
        assertEquals("MyProject\\UserRepository", type2);
        String type3 = types.get(new OffsetRange(72, 77));
        assertEquals("Index", type3);
    }

    public void testValidUseCase_07() throws Exception {
        AnnotationParsedLine parsedLine = parser.parse("document");
        assertEquals("Document", parsedLine.getName());
        assertEquals("", parsedLine.getDescription());
        Map<OffsetRange, String> types = parsedLine.getTypes();
        assertNotNull(types);
        assertEquals(1, types.size());
        String type1 = types.get(new OffsetRange(0, 8));
        assertEquals("document", type1);
    }

    public void testValidUseCase_08() throws Exception {
        AnnotationParsedLine parsedLine = parser.parse("\\Foo\\Bar\\document(repositoryClass=\"MyProject\\UserRepository\", indexes={@Index(keys={\"username\"=\"desc\"}, db=\"documents\", collection=\"users\", options={\"unique\"=true})}, requireIndexes=true)  \t");
        assertEquals("Document", parsedLine.getName());
        assertEquals("(repositoryClass=\"MyProject\\UserRepository\", indexes={@Index(keys={\"username\"=\"desc\"}, db=\"documents\", collection=\"users\", options={\"unique\"=true})}, requireIndexes=true)", parsedLine.getDescription());
        Map<OffsetRange, String> types = parsedLine.getTypes();
        assertNotNull(types);
        assertEquals(3, types.size());
        String type1 = types.get(new OffsetRange(0, 17));
        assertEquals("\\Foo\\Bar\\document", type1);
        String type2 = types.get(new OffsetRange(35, 59));
        assertEquals("MyProject\\UserRepository", type2);
        String type3 = types.get(new OffsetRange(72, 77));
        assertEquals("Index", type3);
    }

}
