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


import static org.apache.directory.server.core.integ.IntegrationUtils.getAdminConnection;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.util.Arrays;

import org.apache.directory.ldap.client.api.LdapConnection;
import org.apache.directory.server.core.annotations.CreateDS;
import org.apache.directory.server.core.factory.DefaultDirectoryServiceFactory;
import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
import org.apache.directory.server.core.integ.FrameworkRunner;
import org.apache.directory.server.core.integ.IntegrationUtils;
import org.apache.directory.shared.ldap.constants.SchemaConstants;
import org.apache.directory.shared.ldap.entry.DefaultEntry;
import org.apache.directory.shared.ldap.entry.Entry;
import org.apache.directory.shared.ldap.entry.EntryAttribute;
import org.apache.directory.shared.ldap.exception.LdapException;
import org.apache.directory.shared.ldap.message.ModifyRequest;
import org.apache.directory.shared.ldap.codec.message.ModifyRequestImpl;
import org.apache.directory.shared.ldap.name.DN;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Used to test the default change log implementation with an in memory
 * change log store.  Note that this will probably be removed since this
 * functionality will be used and tested anyway in all other test cases.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
@RunWith(FrameworkRunner.class)
@CreateDS(factory = DefaultDirectoryServiceFactory.class, name = "DefaultChangeLogIT-class")
public class DefaultChangeLogIT extends AbstractLdapTestUnit
{
    public static final Logger LOG = LoggerFactory.getLogger( DefaultChangeLogIT.class );


    @After
    public void closeConnections()
    {
        IntegrationUtils.closeConnections();
    }


    @Test
    public void testManyTagsPersistenceAcrossRestarts() throws Exception, InterruptedException
    {
        LdapConnection sysRoot = getAdminConnection( service );
        long revision = service.getChangeLog().getCurrentRevision();

        // add new test entry
        Entry entry = new DefaultEntry( new DN( "ou=test0,ou=system" ) );
        entry.add( SchemaConstants.OBJECT_CLASS_AT, "organizationalUnit" );
        entry.add( SchemaConstants.OU_AT, "test0" );
        sysRoot.add( entry );

        assertEquals( revision + 1, service.getChangeLog().getCurrentRevision() );

        Tag t0 = service.getChangeLog().tag();
        assertEquals( t0, service.getChangeLog().getLatest() );
        assertEquals( revision + 1, service.getChangeLog().getCurrentRevision() );
        assertEquals( revision + 1, t0.getRevision() );

        // add another test entry
        entry = new DefaultEntry( new DN( "ou=test1,ou=system" ) );
        entry.add( SchemaConstants.OBJECT_CLASS_AT, "organizationalUnit" );
        entry.put( SchemaConstants.OU_AT, "test1" );
        sysRoot.add( entry );
        assertEquals( revision + 2, service.getChangeLog().getCurrentRevision() );

        Tag t1 = service.getChangeLog().tag();
        assertEquals( t1, service.getChangeLog().getLatest() );
        assertEquals( revision + 2, service.getChangeLog().getCurrentRevision() );
        assertEquals( revision + 2, t1.getRevision() );

        service.shutdown();
        service.startup();

        sysRoot = getAdminConnection( service );
        assertEquals( revision + 2, service.getChangeLog().getCurrentRevision() );
        assertEquals( t1, service.getChangeLog().getLatest() );
        assertEquals( revision + 2, t1.getRevision() );

        // add third test entry
        entry = new DefaultEntry( new DN( "ou=test2,ou=system" ) );
        entry.add( SchemaConstants.OBJECT_CLASS_AT, "organizationalUnit" );
        entry.put( SchemaConstants.OU_AT, "test2" );
        sysRoot.add( entry );
        assertEquals( revision + 3, service.getChangeLog().getCurrentRevision() );

        service.revert();

        assertPresent( sysRoot, "ou=test0,ou=system" ); // test present
        assertPresent( sysRoot, "ou=test1,ou=system" ); // test present

        assertNotPresent( sysRoot, "ou=test2,ou=system" );
        assertEquals( revision + 4, service.getChangeLog().getCurrentRevision() );
        assertEquals( t1, service.getChangeLog().getLatest() );

        service.revert( t0.getRevision() );
        assertPresent( sysRoot, "ou=test0,ou=system" ); // test present
        assertNotPresent( sysRoot, "ou=test1,ou=system" );
        assertNotPresent( sysRoot, "ou=test2,ou=system" );
        assertEquals( revision + 7, service.getChangeLog().getCurrentRevision() );
        assertEquals( t1, service.getChangeLog().getLatest() );

        // no sync this time but should happen automatically
        service.shutdown();
        service.startup();

        sysRoot = getAdminConnection( service );
        assertEquals( revision + 7, service.getChangeLog().getCurrentRevision() );
        assertEquals( t1, service.getChangeLog().getLatest() );
        assertEquals( revision + 2, t1.getRevision() );

        service.revert( revision );
        assertNotPresent( sysRoot, "ou=test0,ou=system" );
        assertNotPresent( sysRoot, "ou=test1,ou=system" );
        assertNotPresent( sysRoot, "ou=test2,ou=system" );
        assertEquals( revision + 14, service.getChangeLog().getCurrentRevision() );
        assertEquals( t1, service.getChangeLog().getLatest() );
    }


    @Test
    public void testTagPersistenceAcrossRestarts() throws Exception, InterruptedException
    {
        LdapConnection sysRoot = getAdminConnection( service );
        long revision = service.getChangeLog().getCurrentRevision();

        Tag t0 = service.getChangeLog().tag();
        assertEquals( t0, service.getChangeLog().getLatest() );
        assertEquals( revision, service.getChangeLog().getCurrentRevision() );

        // add new test entry
        Entry entry = new DefaultEntry( new DN( "ou=test,ou=system" ) );
        entry.add( SchemaConstants.OBJECT_CLASS_AT, "organizationalUnit" );
        entry.put( SchemaConstants.OU_AT, "test" );
        sysRoot.add( entry );
        assertEquals( revision + 1, service.getChangeLog().getCurrentRevision() );

        service.shutdown();
        service.startup();

        sysRoot = getAdminConnection( service );
        assertEquals( revision + 1, service.getChangeLog().getCurrentRevision() );
        assertEquals( t0, service.getChangeLog().getLatest() );

        service.revert();
        assertNotPresent( sysRoot, "ou=test" );
        assertEquals( revision + 2, service.getChangeLog().getCurrentRevision() );
        assertEquals( t0, service.getChangeLog().getLatest() );
    }


    @Test
    public void testRevertAddOperations() throws Exception
    {
        LdapConnection sysRoot = getAdminConnection( service );
        Tag t0 = service.getChangeLog().tag();
        Entry entry = new DefaultEntry( new DN( "ou=test,ou=system" ) );
        entry.add( SchemaConstants.OBJECT_CLASS_AT, "organizationalUnit" );
        entry.put( SchemaConstants.OU_AT, "test" );
        sysRoot.add( entry );

        assertPresent( sysRoot, "ou=test,ou=system" );
        service.revert( t0.getRevision() );

        assertNotPresent( sysRoot, "ou=test,ou=system" );
    }


    @Test
    public void testRevertAddAndDeleteOperations() throws Exception
    {
        LdapConnection sysRoot = getAdminConnection( service );
        Tag t0 = service.getChangeLog().tag();

        // add new test entry
        Entry entry = new DefaultEntry( new DN( "ou=test,ou=system" ) );
        entry.add( SchemaConstants.OBJECT_CLASS_AT, "organizationalUnit" );
        entry.put( SchemaConstants.OU_AT, "test" );
        sysRoot.add( entry );

        // assert presence
        assertPresent( sysRoot, "ou=test,ou=system" );

        // delete the test entry and test that it is gone
        sysRoot.delete( "ou=test,ou=system" );
        assertNotPresent( sysRoot, "ou=test,ou=system" );

        // now revert back to begining the added entry is still gone
        service.revert( t0.getRevision() );
        assertNotPresent( sysRoot, "ou=test" );
    }


    @Test
    public void testRevertDeleteOperations() throws Exception
    {
        LdapConnection sysRoot = getAdminConnection( service );
        Entry entry = new DefaultEntry( new DN( "ou=test,ou=system" ) );
        entry.add( SchemaConstants.OBJECT_CLASS_AT, "organizationalUnit" );
        entry.put( SchemaConstants.OU_AT, "test" );
        sysRoot.add( entry );

        // tag after the addition before deletion
        Tag t0 = service.getChangeLog().tag();
        assertPresent( sysRoot, "ou=test,ou=system" );

        // delete the test entry and test that it is gone
        sysRoot.delete( "ou=test,ou=system" );
        assertNotPresent( sysRoot, "ou=test,ou=system" );

        // now revert and assert that the added entry re-appears
        service.revert( t0.getRevision() );
        assertPresent( sysRoot, "ou=test,ou=system" );
    }


    @Test
    public void testRevertRenameOperations() throws Exception
    {
        LdapConnection sysRoot = getAdminConnection( service );
        Entry entry = new DefaultEntry( new DN( "ou=oldname,ou=system" ) );
        entry.add( SchemaConstants.OBJECT_CLASS_AT, "organizationalUnit" );
        entry.put( SchemaConstants.OU_AT, "oldname" );
        sysRoot.add( entry );

        // tag after the addition before rename
        Tag t0 = service.getChangeLog().tag();
        assertPresent( sysRoot, "ou=oldname,ou=system" );

        // rename the test entry and test that the rename occurred
        sysRoot.rename( "ou=oldname,ou=system", "ou=newname" );
        assertNotPresent( sysRoot, "ou=oldname,ou=system" );
        assertPresent( sysRoot, "ou=newname,ou=system" );

        // now revert and assert that the rename was reversed
        service.revert( t0.getRevision() );
        assertPresent( sysRoot, "ou=oldname,ou=system" );
        assertNotPresent( sysRoot, "ou=newname,ou=system" );

    }


    @Test
    public void testRevertModifyOperations() throws Exception
    {
        LdapConnection sysRoot = getAdminConnection( service );
        Entry entry = new DefaultEntry( new DN( "ou=test5,ou=system" ) );
        entry.add( SchemaConstants.OBJECT_CLASS_AT, "organizationalUnit" );
        entry.put( SchemaConstants.OU_AT, "test5" );
        sysRoot.add( entry );

        // -------------------------------------------------------------------
        // Modify ADD Test
        // -------------------------------------------------------------------

        // tag after the addition before modify ADD
        Tag t0 = service.getChangeLog().tag();
        assertPresent( sysRoot, "ou=test5,ou=system" );

        // modify the test entry to add description and test new attr appears
        ModifyRequest modReq = new org.apache.directory.shared.ldap.codec.message.ModifyRequestImpl();
        modReq.setName( entry.getDn() );
        modReq.add( "description", "a desc value" );
        sysRoot.modify( modReq );

        Entry resusitated = sysRoot.lookup( "ou=test5,ou=system" );
        assertNotNull( resusitated );
        EntryAttribute description = resusitated.get( "description" );
        assertNotNull( description );
        assertEquals( "a desc value", description.getString() );

        // now revert and assert that the added entry re-appears
        service.revert( t0.getRevision() );
        resusitated = sysRoot.lookup( "ou=test5,ou=system" );
        assertNotNull( resusitated );
        assertNull( resusitated.get( "description" ) );

        // -------------------------------------------------------------------
        // Modify REPLACE Test
        // -------------------------------------------------------------------

        // add the attribute again and make sure it is old value
        modReq = new org.apache.directory.shared.ldap.codec.message.ModifyRequestImpl();
        modReq.setName( resusitated.getDn() );
        modReq.add( "description", "old value" );
        sysRoot.modify( modReq );
        resusitated = sysRoot.lookup( "ou=test5,ou=system" );
        assertNotNull( resusitated );
        description = resusitated.get( "description" );
        assertNotNull( description );
        assertEquals( description.getString(), "old value" );

        // now tag then replace the value to "new value" and confirm
        Tag t1 = service.getChangeLog().tag();
        modReq = new org.apache.directory.shared.ldap.codec.message.ModifyRequestImpl();
        modReq.setName( resusitated.getDn() );
        modReq.replace( "description", "new value" );
        sysRoot.modify( modReq );

        resusitated = sysRoot.lookup( "ou=test5,ou=system" );
        assertNotNull( resusitated );
        description = resusitated.get( "description" );
        assertNotNull( description );
        assertEquals( description.getString(), "new value" );

        // now revert and assert the old value is now reverted
        service.revert( t1.getRevision() );
        resusitated = sysRoot.lookup( "ou=test5,ou=system" );
        assertNotNull( resusitated );
        description = resusitated.get( "description" );
        assertNotNull( description );
        assertEquals( description.getString(), "old value" );

        // -------------------------------------------------------------------
        // Modify REMOVE Test
        // -------------------------------------------------------------------

        Tag t2 = service.getChangeLog().tag();
        modReq = new ModifyRequestImpl();
        modReq.setName( resusitated.getDn() );
        modReq.remove( "description", "old value" );
        sysRoot.modify( modReq );

        resusitated = sysRoot.lookup( "ou=test5,ou=system" );
        assertNotNull( resusitated );
        description = resusitated.get( "description" );
        assertNull( description );

        // now revert and assert the old value is now reverted
        service.revert( t2.getRevision() );
        resusitated = sysRoot.lookup( "ou=test5,ou=system" );
        assertNotNull( resusitated );
        description = resusitated.get( "description" );
        assertNotNull( description );
        assertEquals( description.getString(), "old value" );

        // -------------------------------------------------------------------
        // Modify Multi Operation Test
        // -------------------------------------------------------------------

        // add a userPassword attribute so we can test replacing it
        modReq = new org.apache.directory.shared.ldap.codec.message.ModifyRequestImpl();
        modReq.setName( resusitated.getDn() );
        modReq.add( "userPassword", "to be replaced" );
        sysRoot.modify( modReq );
        resusitated = sysRoot.lookup( "ou=test5,ou=system" );
        assertPassword( resusitated, "to be replaced" );

        modReq = new org.apache.directory.shared.ldap.codec.message.ModifyRequestImpl();
        modReq.setName( resusitated.getDn() );
        modReq.remove( "description", "old value" );
        modReq.add( "seeAlso", "ou=added" );
        modReq.replace( "userPassword", "a replaced value" );

        Tag t3 = service.getChangeLog().tag();

        // now make the modification and check that description is gone,
        // seeAlso is added, and that the userPassword has been replaced
        sysRoot.modify( modReq );
        resusitated = sysRoot.lookup( "ou=test5,ou=system" );
        assertNotNull( resusitated );
        description = resusitated.get( "description" );
        assertNull( description );
        assertPassword( resusitated, "a replaced value" );
        EntryAttribute seeAlso = resusitated.get( "seeAlso" );
        assertNotNull( seeAlso );
        assertEquals( seeAlso.getString(), "ou=added" );

        // now we revert and make sure the old values are as they were
        service.revert( t3.getRevision() );
        resusitated = sysRoot.lookup( "ou=test5,ou=system" );
        assertNotNull( resusitated );
        description = resusitated.get( "description" );
        assertNotNull( description );
        assertEquals( description.getString(), "old value" );
        assertPassword( resusitated, "to be replaced" );
        seeAlso = resusitated.get( "seeAlso" );
        assertNull( seeAlso );
    }


    private void assertPassword( Entry entry, String password ) throws Exception
    {
        EntryAttribute userPassword = entry.get( "userPassword" );
        assertNotNull( userPassword );
        assertTrue( Arrays.equals( password.getBytes(), userPassword.getBytes() ) );
    }


    private void assertNotPresent( LdapConnection connection, String dn ) throws LdapException
    {
        Entry se = connection.lookup( dn );
        assertNull( se );
    }


    private void assertPresent( LdapConnection connection, String dn ) throws LdapException
    {
        Entry entry = connection.lookup( dn );
        assertNotNull( entry );
    }
}
