/*
 *  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.apache.directory.shared.ldap.filter;


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.text.ParseException;

import org.junit.Test;


/**
 * Tests the FilterParserImpl class.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev: 575783 $
 */
public class FilterCloneTest
{
    @SuppressWarnings("unchecked")
    @Test
    public void testItemFilter() throws ParseException
    {
        SimpleNode node = ( SimpleNode ) FilterParser.parse( "(ou~=people)" );
        // just check that it doesnt throw for now
        node = (SimpleNode)node.clone();
        assertEquals( "ou", node.getAttribute() );
        assertEquals( "people", node.getValue().getString() );
        assertTrue( node instanceof ApproximateNode );
    }

    
    @Test
    public void testAndFilter() throws ParseException
    {
        BranchNode node = ( BranchNode ) FilterParser.parse( "(&(ou~=people)(age>=30))" );
        // just check that it doesnt throw for now
        node = (BranchNode) node.clone();
        assertEquals( 2, node.getChildren().size() );
        assertTrue( node instanceof AndNode );
    }

    
    @Test
    public void testAndFilterOneChildOnly() throws ParseException
    {
        BranchNode node = ( BranchNode ) FilterParser.parse( "(&(ou~=people))" );
        // just check that it doesnt throw for now
        node = (BranchNode)node.clone();
        assertEquals( 1, node.getChildren().size() );
        assertTrue( node instanceof AndNode );
    }


    @Test
    public void testOrFilter() throws ParseException
    {
        BranchNode node = ( BranchNode ) FilterParser.parse( "(|(ou~=people)(age>=30))" );
        // just check that it doesnt throw for now
        node = (BranchNode)node.clone();
        assertEquals( 2, node.getChildren().size() );
        assertTrue( node instanceof OrNode );
    }


    @Test
    public void testOrFilterOneChildOnly() throws ParseException
    {
        BranchNode node = ( BranchNode ) FilterParser.parse( "(|(age>=30))" );
        // just check that it doesnt throw for now
        node = (BranchNode) node.clone();
        assertEquals( 1, node.getChildren().size() );
        assertTrue( node instanceof OrNode );
    }


    @Test
    public void testNotFilter() throws ParseException
    {
        BranchNode node = ( BranchNode ) FilterParser.parse( "(!(&(ou~= people)(age>=30)))" );
        // just check that it doesnt throw for now
        node = (BranchNode)node.clone();
        assertEquals( 1, node.getChildren().size() );
        assertTrue( node instanceof NotNode );
    }


    @SuppressWarnings("unchecked")
    @Test
    public void testOptionAndEscapesFilter() throws ParseException
    {
        SimpleNode node = ( SimpleNode ) FilterParser.parse( "(ou;lang-de>=\\23\\42asdl fkajsd)" );
        // just check that it doesnt throw for now
        node = (SimpleNode)node.clone();
        assertEquals( "ou;lang-de", node.getAttribute() );
        assertEquals( "#Basdl fkajsd", node.getValue().getString() );
    }


    @SuppressWarnings("unchecked")
    @Test
    public void testOptionsAndEscapesFilter() throws ParseException
    {
        SimpleNode node = ( SimpleNode ) FilterParser.parse( "(ou;lang-de;version-124>=\\23\\42asdl fkajsd)" );
        // just check that it doesnt throw for now
        node = (SimpleNode)node.clone();
        assertEquals( "ou;lang-de;version-124", node.getAttribute() );
        assertEquals( "#Basdl fkajsd", node.getValue().getString() );
    }


    @SuppressWarnings("unchecked")
    @Test
    public void testNumericoidOptionsAndEscapesFilter() throws ParseException
    {
        SimpleNode node = ( SimpleNode ) FilterParser.parse( "(1.3.4.2;lang-de;version-124>=\\23\\42asdl fkajsd)" );
        // just check that it doesnt throw for now
        node = (SimpleNode)node.clone();
        assertEquals( "1.3.4.2;lang-de;version-124", node.getAttribute() );
        assertEquals( "#Basdl fkajsd", node.getValue().getString() );
    }


    @Test
    public void testPresentFilter() throws ParseException
    {
        PresenceNode node = ( PresenceNode ) FilterParser.parse( "(ou=*)" );
        // just check that it doesnt throw for now
        node = (PresenceNode) node.clone();
        assertEquals( "ou", node.getAttribute() );
        assertTrue( node instanceof PresenceNode );
    }


    @Test
    public void testNumericoidPresentFilter() throws ParseException
    {
        PresenceNode node = ( PresenceNode ) FilterParser.parse( "(1.2.3.4=*)" );
        // just check that it doesnt throw for now
        node = ( PresenceNode )node.clone();
        assertEquals( "1.2.3.4", node.getAttribute() );
        assertTrue( node instanceof PresenceNode );
    }


    @SuppressWarnings("unchecked")
    @Test
    public void testEqualsFilter() throws ParseException
    {
        SimpleNode node = ( SimpleNode ) FilterParser.parse( "(ou=people)" );
        // just check that it doesnt throw for now
        node = ( SimpleNode) node.clone();
        assertEquals( "ou", node.getAttribute() );
        assertEquals( "people", node.getValue().getString() );
        assertTrue( node instanceof EqualityNode );
    }


    @SuppressWarnings("unchecked")
    @Test
    public void testEqualsWithForwardSlashFilter() throws ParseException
    {
        SimpleNode node = ( SimpleNode ) FilterParser.parse( "(ou=people/in/my/company)" );
        // just check that it doesnt throw for now
        node = (SimpleNode) node.clone();
        assertEquals( "ou", node.getAttribute() );
        assertEquals( "people/in/my/company", node.getValue().getString() );
        assertTrue( node instanceof EqualityNode );
    }


    @Test
    public void testExtensibleFilterForm1() throws ParseException
    {
        ExtensibleNode node = ( ExtensibleNode ) FilterParser.parse( "(ou:dn:stupidMatch:=dummyAssertion\\23\\2A)" );
        // just check that it doesnt throw for now
        node = ( ExtensibleNode ) node.clone();
        assertEquals( "ou", node.getAttribute() );
        assertEquals( "dummyAssertion#*", node.getValue().getString() );
        assertEquals( "stupidMatch", node.getMatchingRuleId() );
        assertTrue( node.hasDnAttributes() );
        assertTrue( node instanceof ExtensibleNode );
    }


    @Test
    public void testExtensibleFilterForm1WithNumericOid() throws ParseException
    {
        ExtensibleNode node = ( ExtensibleNode ) FilterParser.parse( "(1.2.3.4:dn:1.3434.23.2:=dummyAssertion\\23\\2A)" );
        // just check that it doesnt throw for now
        node = ( ExtensibleNode )node.clone();
        assertEquals( "1.2.3.4", node.getAttribute() );
        assertEquals( "dummyAssertion#*", node.getValue().getString() );
        assertEquals( "1.3434.23.2", node.getMatchingRuleId() );
        assertTrue( node.hasDnAttributes() );
        assertTrue( node instanceof ExtensibleNode );
    }


    @Test
    public void testExtensibleFilterForm1NoDnAttr() throws ParseException
    {
        ExtensibleNode node = ( ExtensibleNode ) FilterParser.parse( "(ou:stupidMatch:=dummyAssertion\\23\\2A)" );
        // just check that it doesnt throw for now
        node = ( ExtensibleNode ) node.clone();
        assertEquals( "ou", node.getAttribute() );
        assertEquals( "dummyAssertion#*", node.getValue().getString() );
        assertEquals( "stupidMatch", node.getMatchingRuleId() );
        assertFalse( node.hasDnAttributes() );
        assertTrue( node instanceof ExtensibleNode );
    }


 
    @Test
    public void testExtensibleFilterForm1NoAttrNoMatchingRule() throws ParseException
    {
        ExtensibleNode node = ( ExtensibleNode ) FilterParser.parse( "(ou:=dummyAssertion\\23\\2A)" );
        // just check that it doesnt throw for now
        node = (ExtensibleNode) node.clone();
        assertEquals( "ou", node.getAttribute() );
        assertEquals( "dummyAssertion#*", node.getValue().getString() );
        assertEquals( null, node.getMatchingRuleId() );
        assertFalse( node.hasDnAttributes() );
        assertTrue( node instanceof ExtensibleNode );
    }


    @Test
    public void testExtensibleFilterForm2() throws ParseException
    {
        ExtensibleNode node = ( ExtensibleNode ) FilterParser.parse( "(:dn:stupidMatch:=dummyAssertion\\23\\2A)" );
        // just check that it doesnt throw for now
        node = ( ExtensibleNode ) node.clone();
        assertEquals( null, node.getAttribute() );
        assertEquals( "dummyAssertion#*", node.getValue().getString() );
        assertEquals( "stupidMatch", node.getMatchingRuleId() );
        assertTrue( node.hasDnAttributes() );
        assertTrue( node instanceof ExtensibleNode );
    }


    @Test
    public void testExtensibleFilterForm2WithNumericOid() throws ParseException
    {
        ExtensibleNode node = ( ExtensibleNode ) FilterParser.parse( "(:dn:1.3434.23.2:=dummyAssertion\\23\\2A)" );
        assertEquals( null, node.getAttribute() );
        assertEquals( "dummyAssertion#*", node.getValue().getString() );
        assertEquals( "1.3434.23.2", node.getMatchingRuleId() );
        assertTrue( node.hasDnAttributes() );
        assertTrue( node instanceof ExtensibleNode );
    }


    @Test
    public void testExtensibleFilterForm2NoDnAttr() throws ParseException
    {
        ExtensibleNode node1 = ( ExtensibleNode ) FilterParser.parse( "(:stupidMatch:=dummyAssertion\\23\\2A)" );
        // just check that it doesnt throw for now
        ExtensibleNode node = ( ExtensibleNode )node1.clone();
        assertEquals( null, node.getAttribute() );
        assertEquals( "dummyAssertion#*", node.getValue().getString() );
        assertEquals( "stupidMatch", node.getMatchingRuleId() );
        assertFalse( node.hasDnAttributes() );
        assertTrue( node instanceof ExtensibleNode );
    }


    @Test
    public void testExtensibleFilterForm2NoDnAttrWithNumericOidNoAttr() throws ParseException
    {
        ExtensibleNode node = ( ExtensibleNode ) FilterParser.parse( "(:1.3434.23.2:=dummyAssertion\\23\\2A)" );
        // just check that it doesnt throw for now
        node = ( ExtensibleNode) node.clone();
        assertEquals( null, node.getAttribute() );
        assertEquals( "dummyAssertion#*", node.getValue().getString() );
        assertEquals( "1.3434.23.2", node.getMatchingRuleId() );
        assertFalse( node.hasDnAttributes() );
        assertTrue( node instanceof ExtensibleNode );
    }


    @Test
    public void testSubstringNoAnyNoFinal() throws ParseException
    {
        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=foo*)" );
        // just check that it doesnt throw for now
        node = ( SubstringNode ) node.clone();
        assertEquals( "ou", node.getAttribute() );
        assertTrue( node instanceof SubstringNode );
        assertEquals( 0, node.getAny().size() );
        assertFalse( node.getAny().contains( "" ) );
        assertEquals( "foo", node.getInitial() );
        assertEquals( null, node.getFinal() );
    }


    @Test
    public void testSubstringNoAny() throws ParseException
    {
        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=foo*bar)" );
        // just check that it doesnt throw for now
        node = ( SubstringNode ) node.clone();
        assertEquals( "ou", node.getAttribute() );
        assertTrue( node instanceof SubstringNode );
        assertEquals( 0, node.getAny().size() );
        assertFalse( node.getAny().contains( "" ) );
        assertEquals( "foo", node.getInitial() );
        assertEquals( "bar", node.getFinal() );
    }


    @Test
    public void testSubstringNoAnyNoIni() throws ParseException
    {
        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=*bar)" );
        // just check that it doesnt throw for now
        node = ( SubstringNode )node.clone();
        assertEquals( "ou", node.getAttribute() );
        assertTrue( node instanceof SubstringNode );
        assertEquals( 0, node.getAny().size() );
        assertFalse( node.getAny().contains( "" ) );
        assertEquals( null, node.getInitial() );
        assertEquals( "bar", node.getFinal() );
    }


    @Test
    public void testSubstringOneAny() throws ParseException
    {
        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=foo*guy*bar)" );
        // just check that it doesnt throw for now
        node = ( SubstringNode )node.clone();
        assertEquals( "ou", node.getAttribute() );
        assertTrue( node instanceof SubstringNode );
        assertEquals( 1, node.getAny().size() );
        assertFalse( node.getAny().contains( "" ) );
        assertTrue( node.getAny().contains( "guy" ) );
        assertEquals( "foo", node.getInitial() );
        assertEquals( "bar", node.getFinal() );
    }


    @Test
    public void testSubstringManyAny() throws ParseException
    {
        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=a*b*c*d*e*f)" );
        // just check that it doesnt throw for now
        node = ( SubstringNode )node.clone();
        assertEquals( "ou", node.getAttribute() );
        assertTrue( node instanceof SubstringNode );
        assertEquals( 4, node.getAny().size() );
        assertFalse( node.getAny().contains( "" ) );
        assertTrue( node.getAny().contains( "b" ) );
        assertTrue( node.getAny().contains( "c" ) );
        assertTrue( node.getAny().contains( "d" ) );
        assertTrue( node.getAny().contains( "e" ) );
        assertEquals( "a", node.getInitial() );
        assertEquals( "f", node.getFinal() );
    }


    @Test
    public void testSubstringNoIniManyAny() throws ParseException
    {
        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=*b*c*d*e*f)" );
        // just check that it doesnt throw for now
        node = ( SubstringNode )node.clone();
        assertEquals( "ou", node.getAttribute() );
        assertTrue( node instanceof SubstringNode );
        assertEquals( 4, node.getAny().size() );
        assertFalse( node.getAny().contains( "" ) );
        assertTrue( node.getAny().contains( "e" ) );
        assertTrue( node.getAny().contains( "b" ) );
        assertTrue( node.getAny().contains( "c" ) );
        assertTrue( node.getAny().contains( "d" ) );
        assertEquals( null, node.getInitial() );
        assertEquals( "f", node.getFinal() );
    }


    @Test
    public void testSubstringManyAnyNoFinal() throws ParseException
    {
        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=a*b*c*d*e*)" );
        // just check that it doesnt throw for now
        node = ( SubstringNode )node.clone();
        assertEquals( "ou", node.getAttribute() );
        assertTrue( node instanceof SubstringNode );
        assertEquals( 4, node.getAny().size() );
        assertFalse( node.getAny().contains( "" ) );
        assertTrue( node.getAny().contains( "e" ) );
        assertTrue( node.getAny().contains( "b" ) );
        assertTrue( node.getAny().contains( "c" ) );
        assertTrue( node.getAny().contains( "d" ) );
        assertEquals( "a", node.getInitial() );
        assertEquals( null, node.getFinal() );
    }


    @Test
    public void testSubstringNoIniManyAnyNoFinal() throws ParseException
    {
        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=*b*c*d*e*)" );
        // just check that it doesnt throw for now
        node = ( SubstringNode ) node.clone();
        
        assertEquals( "ou", node.getAttribute() );
        assertTrue( node instanceof SubstringNode );
        assertEquals( 4, node.getAny().size() );
        assertFalse( node.getAny().contains( "" ) );
        assertTrue( node.getAny().contains( "e" ) );
        assertTrue( node.getAny().contains( "b" ) );
        assertTrue( node.getAny().contains( "c" ) );
        assertTrue( node.getAny().contains( "d" ) );
        assertEquals( null, node.getInitial() );
        assertEquals( null, node.getFinal() );
    }


    @Test
    public void testSubstringNoAnyDoubleSpaceStar() throws ParseException
    {
        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=foo* *bar)" );
        // just check that it doesnt throw for now
        node = ( SubstringNode )node.clone();
        
        assertEquals( "ou", node.getAttribute() );
        assertTrue( node instanceof SubstringNode );
        assertEquals( 1, node.getAny().size() );
        assertFalse( node.getAny().contains( "" ) );
        assertTrue( node.getAny().contains( " " ) );
        assertEquals( "foo", node.getInitial() );
        assertEquals( "bar", node.getFinal() );
    }


    @Test
    public void testSubstringAnyDoubleSpaceStar() throws ParseException
    {
        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=foo* a *bar)" );
        // just check that it doesnt throw for now
        node = ( SubstringNode ) node.clone();
        
        assertEquals( "ou", node.getAttribute() );
        assertTrue( node instanceof SubstringNode );
        assertEquals( 1, node.getAny().size() );
        assertFalse( node.getAny().contains( "" ) );
        assertTrue( node.getAny().contains( " a " ) );
        assertEquals( "foo", node.getInitial() );
        assertEquals( "bar", node.getFinal() );
    }


    /**
     * Enrique just found this bug with the filter parser when parsing substring
     * expressions like *any*. Here's the JIRA issue: <a
     * href="http://nagoya.apache.org/jira/browse/DIRLDAP-21">DIRLDAP-21</a>.
     */
    @Test
    public void testSubstringStarAnyStar() throws ParseException
    {
        SubstringNode node = ( SubstringNode ) FilterParser.parse( "(ou=*foo*)" );
        // just check that it doesnt throw for now
        node = ( SubstringNode )node.clone();
        
        assertEquals( "ou", node.getAttribute() );
        assertTrue( node instanceof SubstringNode );
        assertEquals( 1, node.getAny().size() );
        assertTrue( node.getAny().contains( "foo" ) );
        assertNull( node.getInitial() );
        assertNull( node.getFinal() );
    }
    
    
    @SuppressWarnings("unchecked")
    @Test
    public void testEqualsFilterNullValue() throws ParseException
    {
        SimpleNode node = ( SimpleNode ) FilterParser.parse( "(ou=)" );
        // just check that it doesnt throw for now
        node = ( SimpleNode )node.clone();
        
        assertEquals( "ou", node.getAttribute() );
        assertEquals( "", node.getValue().getString() );
        assertTrue( node instanceof EqualityNode );
    }


    /**
     * test a filter with a # in value
     */
    @SuppressWarnings("unchecked")
    @Test
    public void testEqualsFilterWithPoundInValue() throws ParseException
    {
        SimpleNode node = ( SimpleNode ) FilterParser.parse( "(uid=#f1)" );
        // just check that it doesnt throw for now
        node = ( SimpleNode ) node.clone();
        assertEquals( "uid", node.getAttribute() );
        assertEquals( "#f1", node.getValue().getString() );
        assertTrue( node instanceof EqualityNode );
    }

    
    @Test
    public void testLargeBusyFilter() throws ParseException
    {
        ExprNode node1 = FilterParser.parse( "(&(|(2.5.4.3=h*)(2.5.4.4=h*)(2.16.840.1.113730.3.1.241=h*)(2.5.4.42=h*))(!(objectClass=computer))(|(objectClass=person)(objectClass=group)(objectClass=organizationalUnit)(objectClass=domain))(!(&(userAccountControl:1.2.840.113556.1.4.803:=2))))" );
        // just check that it doesnt throw for now
        ExprNode node = node1.clone();
        assertTrue(node instanceof AndNode);
        //TODO test full structure
    }
}
