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


import java.util.Hashtable;

import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.AttributeInUseException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InvalidAttributeIdentifierException;
import javax.naming.directory.InvalidAttributeValueException;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

import org.apache.directory.server.unit.AbstractServerTest;
import org.apache.directory.shared.ldap.message.LockableAttributeImpl;
import org.apache.directory.shared.ldap.message.LockableAttributesImpl;
import org.apache.directory.shared.ldap.message.ModificationItemImpl;


/**
 * Testcase with different modify operations on a person entry. Each includes a
 * single add op only. Created to demonstrate DIREVE-241 ("Adding an already
 * existing attribute value with a modify operation does not cause an error.").
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$
 */
public class ModifyAddTest extends AbstractServerTest
{
    private LdapContext ctx = null;
    public static final String RDN = "cn=Tori Amos";
    public static final String PERSON_DESCRIPTION = "an American singer-songwriter";


    /**
     * Creation of required attributes of a person entry.
     */
    protected Attributes getPersonAttributes( String sn, String cn )
    {
        Attributes attributes = new LockableAttributesImpl();
        Attribute attribute = new LockableAttributeImpl( "objectClass" );
        attribute.add( "top" );
        attribute.add( "person" );
        attributes.put( attribute );
        attributes.put( "cn", cn );
        attributes.put( "sn", sn );

        return attributes;
    }


    /**
     * Create context and a person entry.
     */
    protected void setUp() throws Exception
    {
        super.setUp();

        Hashtable env = new Hashtable();
        env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
        env.put( "java.naming.provider.url", "ldap://localhost:" + port + "/ou=system" );
        env.put( "java.naming.security.principal", "uid=admin,ou=system" );
        env.put( "java.naming.security.credentials", "secret" );
        env.put( "java.naming.security.authentication", "simple" );

        ctx = new InitialLdapContext( env, null );
        assertNotNull( ctx );

        // Create a person with description
        Attributes attributes = this.getPersonAttributes( "Amos", "Tori Amos" );
        attributes.put( "description", "an American singer-songwriter" );
        ctx.createSubcontext( RDN, attributes );

    }


    /**
     * Remove person entry and close context.
     */
    protected void tearDown() throws Exception
    {
        ctx.unbind( RDN );
        ctx.close();
        ctx = null;
        super.tearDown();
    }


    /**
     * Add a new attribute to a person entry.
     * 
     * @throws NamingException
     */
    public void testAddNewAttributeValue() throws NamingException
    {
        // Add telephoneNumber attribute
        String newValue = "1234567890";
        Attributes attrs = new LockableAttributesImpl( "telephoneNumber", newValue );
        ctx.modifyAttributes( RDN, DirContext.ADD_ATTRIBUTE, attrs );

        // Verify, that attribute value is added
        attrs = ctx.getAttributes( RDN );
        Attribute attr = attrs.get( "telephoneNumber" );
        assertNotNull( attr );
        assertTrue( attr.contains( newValue ) );
        assertEquals( 1, attr.size() );
    }


    /**
     * Add a new attribute with two values.
     * 
     * @throws NamingException
     */
    public void testAddNewAttributeValues() throws NamingException
    {
        // Add telephoneNumber attribute
        String[] newValues =
            { "1234567890", "999999999" };
        Attribute attr = new LockableAttributeImpl( "telephoneNumber" );
        attr.add( newValues[0] );
        attr.add( newValues[1] );
        Attributes attrs = new LockableAttributesImpl();
        attrs.put( attr );
        ctx.modifyAttributes( RDN, DirContext.ADD_ATTRIBUTE, attrs );

        // Verify, that attribute values are present
        attrs = ctx.getAttributes( RDN );
        attr = attrs.get( "telephoneNumber" );
        assertNotNull( attr );
        assertTrue( attr.contains( newValues[0] ) );
        assertTrue( attr.contains( newValues[1] ) );
        assertEquals( newValues.length, attr.size() );
    }


    /**
     * Add an additional value.
     * 
     * @throws NamingException
     */
    public void testAddAdditionalAttributeValue() throws NamingException
    {
        // A new description attribute value
        String newValue = "A new description for this person";
        assertFalse( newValue.equals( PERSON_DESCRIPTION ) );
        Attributes attrs = new LockableAttributesImpl( "description", newValue );

        ctx.modifyAttributes( RDN, DirContext.ADD_ATTRIBUTE, attrs );

        // Verify, that attribute value is added
        attrs = ctx.getAttributes( RDN );
        Attribute attr = attrs.get( "description" );
        assertNotNull( attr );
        assertTrue( attr.contains( newValue ) );
        assertTrue( attr.contains( PERSON_DESCRIPTION ) );
        assertEquals( 2, attr.size() );
    }


    /**
     * Try to add an already existing attribute value.
     * 
     * Expected behaviour: Modify operation fails with an
     * AttributeInUseException. Original LDAP Error code: 20 (Indicates that the
     * attribute value specified in a modify or add operation already exists as
     * a value for that attribute).
     * 
     * @throws NamingException
     */
    public void testAddExistingAttributeValue() throws NamingException
    {
        // Change description attribute
        Attributes attrs = new LockableAttributesImpl( "description", PERSON_DESCRIPTION );
        
        try
        {
            ctx.modifyAttributes( RDN, DirContext.ADD_ATTRIBUTE, attrs );
            fail( "Adding an already existing atribute value should fail." );
        }
        catch ( AttributeInUseException e )
        {
            // expected behaviour
        }

        // Verify, that attribute is still there, and is the only one
        attrs = ctx.getAttributes( RDN );
        Attribute attr = attrs.get( "description" );
        assertNotNull( attr );
        assertTrue( attr.contains( PERSON_DESCRIPTION ) );
        assertEquals( 1, attr.size() );
    }

    /**
     * Try to add an already existing attribute value.
     * 
     * Expected behaviour: Modify operation fails with an
     * AttributeInUseException. Original LDAP Error code: 20 (Indicates that the
     * attribute value specified in a modify or add operation already exists as
     * a value for that attribute).
     * 
     * Check for bug DIR_SERVER664
     * 
     * @throws NamingException
     */
    public void testAddExistingNthAttributesDirServer664() throws NamingException
    {
        // Change description attribute
        Attributes attrs = new LockableAttributesImpl( true );
        attrs.put( new LockableAttributeImpl( "attr1", "attr 1" ) );
        attrs.put( new LockableAttributeImpl( "attr2", "attr 2" ) );
        attrs.put( new LockableAttributeImpl( "attr3", "attr 3" ) );
        attrs.put( new LockableAttributeImpl( "attr4", "attr 4" ) );
        attrs.put( new LockableAttributeImpl( "attr5", "attr 5" ) );
        attrs.put( new LockableAttributeImpl( "attr6", "attr 6" ) );
        attrs.put( new LockableAttributeImpl( "attr7", "attr 7" ) );
        attrs.put( new LockableAttributeImpl( "attr8", "attr 8" ) );
        attrs.put( new LockableAttributeImpl( "attr9", "attr 9" ) );
        attrs.put( new LockableAttributeImpl( "attr10", "attr 10" ) );
        attrs.put( new LockableAttributeImpl( "attr11", "attr 11" ) );
        attrs.put( new LockableAttributeImpl( "attr12", "attr 12" ) );
        attrs.put( new LockableAttributeImpl( "attr13", "attr 13" ) );
        attrs.put( new LockableAttributeImpl( "attr14", "attr 14" ) );
        
        Attribute attr = new LockableAttributeImpl( "description", PERSON_DESCRIPTION );

        attrs.put( attr );
        
        try
        {
            ctx.modifyAttributes( RDN, DirContext.ADD_ATTRIBUTE, attrs );
            fail( "Adding an already existing atribute value should fail." );
        }
        catch ( AttributeInUseException e )
        {
            // expected behaviour
        }

        // Verify, that attribute is still there, and is the only one
        attrs = ctx.getAttributes( RDN );
        attr = attrs.get( "description" );
        assertNotNull( attr );
        assertTrue( attr.contains( PERSON_DESCRIPTION ) );
        assertEquals( 1, attr.size() );
    }

    /**
     * Check for DIR_SERVER_643
     * 
     * @throws NamingException
     */
    public void testTwoDescriptionDirServer643() throws NamingException
    {
        // Change description attribute
        Attributes attrs = new LockableAttributesImpl( true );
        Attribute attr = new LockableAttributeImpl( "description", "a British singer-songwriter with an expressive four-octave voice" );
        attr.add( "one of the most influential female artists of the twentieth century" );
        attrs.put( attr );
        
        ctx.modifyAttributes( RDN, DirContext.ADD_ATTRIBUTE, attrs );

        // Verify, that attribute is still there, and is the only one
        attrs = ctx.getAttributes( RDN );
        attr = attrs.get( "description" );
        assertNotNull( attr );
        assertEquals( 3, attr.size() );
        assertTrue( attr.contains( "a British singer-songwriter with an expressive four-octave voice" ) );
        assertTrue( attr.contains( "one of the most influential female artists of the twentieth century" ) );
        assertTrue( attr.contains( PERSON_DESCRIPTION ) );
    }

    /**
     * Try to add a duplicate attribute value to an entry, where this attribute
     * is already present (objectclass in this case). Expected behaviour is that
     * the modify operation causes an error (error code 20, "Attribute or value
     * exists").
     * 
     * @throws NamingException
     */
    public void testAddDuplicateValueToExistingAttribute() throws NamingException
    {
        // modify object classes, add a new value twice
        Attribute ocls = new LockableAttributeImpl( "objectClass", "organizationalPerson" );
        ModificationItemImpl[] modItems = new ModificationItemImpl[2];
        modItems[0] = new ModificationItemImpl( DirContext.ADD_ATTRIBUTE, ocls );
        modItems[1] = new ModificationItemImpl( DirContext.ADD_ATTRIBUTE, ocls );
        try
        {
            ctx.modifyAttributes( RDN, modItems );
            fail( "Adding a duplicate attribute value should cause an error." );
        }
        catch ( AttributeInUseException ex )
        {
        }

        // Check, whether attribute objectClass is unchanged
        Attributes attrs = ctx.getAttributes( RDN );
        ocls = attrs.get( "objectClass" );
        assertEquals( ocls.size(), 2 );
        assertTrue( ocls.contains( "top" ) );
        assertTrue( ocls.contains( "person" ) );
    }


    /**
     * Try to add a duplicate attribute value to an entry, where this attribute
     * is not present. Expected behaviour is that the modify operation causes an
     * error (error code 20, "Attribute or value exists").
     * 
     * @throws NamingException
     */
    public void testAddDuplicateValueToNewAttribute() throws NamingException
    {
        // add the same description value twice
        Attribute desc = new LockableAttributeImpl( "description", "another description value besides songwriter" );
        ModificationItemImpl[] modItems = new ModificationItemImpl[2];
        modItems[0] = new ModificationItemImpl( DirContext.ADD_ATTRIBUTE, desc );
        modItems[1] = new ModificationItemImpl( DirContext.ADD_ATTRIBUTE, desc );
        try
        {
            ctx.modifyAttributes( RDN, modItems );
            fail( "Adding a duplicate attribute value should cause an error." );
        }
        catch ( AttributeInUseException ex )
        {
        }

        // Check, whether attribute description is still not present
        Attributes attrs = ctx.getAttributes( RDN );
        assertEquals( 1, attrs.get( "description" ).size() );
    }


    /**
     * Create an entry with a bad attribute : this should fail.
     * 
     * @throws NamingException
     */
    public void testAddUnexistingAttribute() throws NamingException
    {
        Hashtable env = new Hashtable();
        env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
        env.put( "java.naming.provider.url", "ldap://localhost:" + port + "/ou=system" );
        env.put( "java.naming.security.principal", "uid=admin,ou=system" );
        env.put( "java.naming.security.credentials", "secret" );
        env.put( "java.naming.security.authentication", "simple" );

        ctx = new InitialLdapContext( env, null );
        assertNotNull( ctx );

        // Create a third person with a voice attribute
        Attributes attributes = this.getPersonAttributes( "Jackson", "Michael Jackson" );
        attributes.put( "voice", "He is bad ..." );

        try
        {
            ctx.createSubcontext( "cn=Mickael Jackson", attributes );
        }
        catch ( InvalidAttributeIdentifierException iaie )
        {
            assertTrue( true );
            return;
        }

        fail( "Should never reach this point" );
    }


    /**
     * Modu=ify the entry with a bad attribute : this should fail 
     * 
     * @throws NamingException
     */
    public void testSearchBadAttribute() throws NamingException
    {
        // Add a not existing attribute
        String newValue = "unbelievable";
        Attributes attrs = new LockableAttributesImpl( "voice", newValue );

        try
        {
            ctx.modifyAttributes( RDN, DirContext.ADD_ATTRIBUTE, attrs );
        }
        catch ( InvalidAttributeIdentifierException iaie )
        {
            // We have a failure : the attribute is unknown in the schema
            assertTrue( true );
            return;
        }

        fail( "Cannot reach this point" );
    }
    
    
    /**
     * Create a person entry and perform a modify op, in which
     * we modify an attribute two times.
     */
    public void testAttributeValueMultiMofificationDIRSERVER_636() throws NamingException {

        // Create a person entry
        Attributes attrs = getPersonAttributes("Bush", "Kate Bush");
        String rdn = "cn=Kate Bush";
        ctx.createSubcontext(rdn, attrs);

        // Add a decsription with two values
        String[] descriptions = {
                "Kate Bush is a British singer-songwriter.",
                "She has become one of the most influential female artists of the twentieth century." };
        Attribute desc1 = new LockableAttributeImpl("description");
        desc1.add(descriptions[0]);
        desc1.add(descriptions[1]);

        ModificationItemImpl addModOp = new ModificationItemImpl(
                DirContext.ADD_ATTRIBUTE, desc1);

        Attribute desc2 = new LockableAttributeImpl("description");
        desc2.add(descriptions[1]);
        ModificationItemImpl delModOp = new ModificationItemImpl(
                DirContext.REMOVE_ATTRIBUTE, desc2);

        ctx.modifyAttributes(rdn, new ModificationItemImpl[] { addModOp,
                        delModOp });

        SearchControls sctls = new SearchControls();
        sctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
        String filter = "(sn=Bush)";
        String base = "";

        // Check entry
        NamingEnumeration enm = ctx.search(base, filter, sctls);
        assertTrue(enm.hasMore());
        
        while (enm.hasMore()) {
            SearchResult sr = (SearchResult) enm.next();
            attrs = sr.getAttributes();
            Attribute desc = sr.getAttributes().get("description");
            assertNotNull(desc);
            assertEquals(1, desc.size());
            assertTrue(desc.contains(descriptions[0]));
        }

        // Remove the person entry
        ctx.destroySubcontext(rdn);
    }

    /**
     * Create a person entry and perform a modify op on an
     * attribute which is part of the DN. This is not allowed.
     * 
     * A JIRA has been created for this bug : DIRSERVER_687
     */
    /*
     public void testDNAttributeMemberMofificationDIRSERVER_687() throws NamingException {

        // Create a person entry
        Attributes attrs = getPersonAttributes("Bush", "Kate Bush");
        String rdn = "cn=Kate Bush";
        ctx.createSubcontext(rdn, attrs);

        // Try to modify the cn attribute
        Attribute desc1 = new BasicAttribute( "cn", "Georges Bush" );

        ModificationItem addModOp = new ModificationItem(
                DirContext.REPLACE_ATTRIBUTE, desc1);

        try
        {
            ctx.modifyAttributes( rdn, new ModificationItem[] { addModOp } );
        }
        catch ( AttributeModificationException ame )
        {
            assertTrue( true );
            // Remove the person entry
            ctx.destroySubcontext(rdn);
        }
        catch ( NamingException ne ) 
        {
            assertTrue( true );
            // Remove the person entry
            ctx.destroySubcontext(rdn);
        }

        // Remove the person entry
        ctx.destroySubcontext(rdn);

        fail();
    }
    */
    
    /**
     * Try to modify an entry adding invalid number of values for a single-valued atribute
     * @see http://issues.apache.org/jira/browse/DIRSERVER-614
     */
    public void testModifyAddWithInvalidNumberOfAttributeValues() throws NamingException
    {
        Attributes attrs = new LockableAttributesImpl();
        Attribute ocls = new LockableAttributeImpl( "objectClass" );
        ocls.add( "top" );
        ocls.add( "inetOrgPerson" );
        attrs.put( ocls );
        attrs.put( "cn", "Fiona Apple" );
        attrs.put( "sn", "Apple" );
        ctx.createSubcontext( "cn=Fiona Apple", attrs );
        
        // add two displayNames to an inetOrgPerson
        attrs = new LockableAttributesImpl();
        Attribute displayName = new LockableAttributeImpl( "displayName" );
        displayName.add( "Fiona" );
        displayName.add( "Fiona A." );
        attrs.put( displayName );
        
        try
        {
            ctx.modifyAttributes( "cn=Fiona Apple", DirContext.ADD_ATTRIBUTE, attrs );
            fail( "modification of entry should fail" );
        }
        catch ( InvalidAttributeValueException e )
        {
            
        }
    }
}
