/*
 *   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.ldap.client.api;


import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.directory.api.ldap.model.constants.SchemaConstants;
import org.apache.directory.api.ldap.model.entry.Attribute;
import org.apache.directory.api.ldap.model.entry.DefaultAttribute;
import org.apache.directory.api.ldap.model.entry.DefaultEntry;
import org.apache.directory.api.ldap.model.entry.DefaultModification;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.entry.Modification;
import org.apache.directory.api.ldap.model.entry.Value;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
import org.apache.directory.api.ldap.model.ldif.ChangeType;
import org.apache.directory.api.ldap.model.ldif.LdifEntry;
import org.apache.directory.api.ldap.model.ldif.LdifReader;
import org.apache.directory.api.ldap.model.ldif.LdifUtils;
import org.apache.directory.api.ldap.model.ldif.anonymizer.Anonymizer;
import org.apache.directory.api.ldap.model.ldif.anonymizer.BinaryAnonymizer;
import org.apache.directory.api.ldap.model.ldif.anonymizer.CaseSensitiveStringAnonymizer;
import org.apache.directory.api.ldap.model.ldif.anonymizer.IntegerAnonymizer;
import org.apache.directory.api.ldap.model.ldif.anonymizer.StringAnonymizer;
import org.apache.directory.api.ldap.model.ldif.anonymizer.TelephoneNumberAnonymizer;
import org.apache.directory.api.ldap.model.name.Ava;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.api.ldap.model.name.Rdn;
import org.apache.directory.api.ldap.model.schema.AttributeType;
import org.apache.directory.api.ldap.model.schema.LdapSyntax;
import org.apache.directory.api.ldap.model.schema.SchemaManager;
import org.apache.directory.api.ldap.model.schema.syntaxCheckers.DnSyntaxChecker;
import org.apache.directory.api.ldap.model.schema.syntaxCheckers.NameAndOptionalUIDSyntaxChecker;
import org.apache.directory.api.ldap.schema.manager.impl.DefaultSchemaManager;


/**
 * Anonymize the content of a LDIF file.
 * 
 * We will replace the values of the defined attributes with random chars. There are a default
 * list of attributes that are going to be anonymized :
 * <ul>
 * <li>userPassword</li>
 * <li>displayName</li>
 * <li>givenName</li>
 * <li>surName</li>
 * <li>homePhone</li>
 * <li>homePostalAddress</li>
 * <li>jpegPhoto</li>
 * <li>labeledURI</li>
 * <li>mail</li>
 * <li>manager</li>
 * <li>mobile</li>
 * <li>organizationName</li>
 * <li>pager</li>
 * <li>photo</li>
 * <li>secretary</li>
 * <li>uid</li>
 * <li>userCertificate</li>
 * <li>userPKCS12</li>
 * <li>userSMIMECertificate</li>
 * <li>x500UniqueIdentifier</li>
 * <li>carLicense</li>
 * <li>host</li>
 * <li>locality</li>
 * <li>organizationName</li>
 * <li>organizationalUnitName</li>
 * <li>seelAlso</li>
 * <li>homeDirectory</li>
 * <li>uidNumber</li>
 * <li>gidNumber</li>
 * <li>commonName</li>
 * <li>gecos</li>
 * <li>description</li>
 * <li>memberUid</li>
 * </ul>
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class LdifAnonymizer
{
    /** The map that stores the anonymized values associated to the original value */
    private Map<Value, Value> valueMap = new HashMap<>();
    
    /** The set that contains all the values we already have anonymized */
    private Set<Value> valueSet = new HashSet<>();
    
    /** The latest anonymized String value Map */
    private Map<Integer, String> latestStringMap;
    
    /** The latest anonymized byte[] value Map */
    private Map<Integer, byte[]> latestBytesMap;
    
    /** The map of AttributeType'sOID we want to anonymize. They are all associated with anonymizers */
    private Map<String, Anonymizer> attributeAnonymizers = new HashMap<>();
    
    /** The list of existing NamingContexts */
    private Set<Dn> namingContexts = new HashSet<>();

    /** The schemaManager */
    private SchemaManager schemaManager;
    
    /** The PrintStream used to write informations about the processing */
    private PrintStream out = null;

    /**
     * Creates a default instance of LdifAnonymizer. The list of anonymized attribute
     * is set to a default value.
     *
     */
    public LdifAnonymizer()
    {
        try
        {
            schemaManager = new DefaultSchemaManager();
        }
        catch ( Exception e )
        {
            println( "Missing a SchemaManager !" );
            System.exit( -1 );
        }

        init( null, null, null, null );
    }
    
    
    /**
     * Creates a default instance of LdifAnonymizer. The list of anonymized attribute
     * is set to a default value.
     * 
     * @param schemaManager The SchemaManager instance we will use
     */
    public LdifAnonymizer( SchemaManager schemaManager )
    {
        this.schemaManager = schemaManager;

        init( null, null, null, null );
    }
    
    
    /**
     * Set the PrintStream to use to print information about the processing
     * 
     * @param out The PrintStream to use
     */
    public void setOut( PrintStream out )
    {
        this.out = out;
    }
    
    
    /**
     * Print the string into the PrintStream, with a NL at the end
     * 
     * @param str The string to print
     */
    private void println( String str )
    {
        if ( out != null )
        {
            out.println( str );
        }
    }
    
    
    /**
     * Print a nl into the PrintStream
     */
    private void println()
    {
        if ( out != null )
        {
            out.println();
        }
    }
    

    /**
     * Initialize the anonymizer, filling the maps we use.
     * 
     * @param stringLatestValueMap The map of already seen Strings
     * @param binaryLatestValueMap The map of already seen byte[]
     * @param integerLatestValueMap  The map of already seen Integers
     * @param telephoneNumberLatestValueMap   The map of already seen telephone numbers
     */
    private void init( Map<Integer, String> stringLatestValueMap, Map<Integer, byte[]> binaryLatestValueMap, 
        Map<Integer, String> integerLatestValueMap, Map<Integer, String> telephoneNumberLatestValueMap )
    {
        // Load the anonymizers
        attributeAnonymizers.put( SchemaConstants.CAR_LICENSE_AT_OID,
            new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.DOMAIN_COMPONENT_AT_OID,
            new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.CN_AT_OID, new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.DESCRIPTION_AT_OID,
            new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.DISPLAY_NAME_AT_OID,
            new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.GECOS_AT_OID, new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.GID_NUMBER_AT_OID,
            new IntegerAnonymizer( integerLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.GIVENNAME_AT_OID,
            new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.HOME_DIRECTORY_AT_OID,
            new CaseSensitiveStringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.HOME_PHONE_AT_OID,
            new TelephoneNumberAnonymizer() );
        attributeAnonymizers.put( SchemaConstants.HOME_POSTAL_ADDRESS_AT_OID,
            new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.HOST_AT_OID, new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.HOUSE_IDENTIFIER_AT_OID,
            new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.JPEG_PHOTO_AT_OID,
            new BinaryAnonymizer( binaryLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.LABELED_URI_AT_OID,
            new CaseSensitiveStringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.LOCALITY_NAME_AT_OID,
            new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.MAIL_AT_OID, new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.MANAGER_AT_OID, new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.MEMBER_UID_AT_OID,
            new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.MOBILE_AT_OID, new TelephoneNumberAnonymizer() );
        attributeAnonymizers.put( SchemaConstants.ORGANIZATION_NAME_AT_OID,
            new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.ORGANIZATIONAL_UNIT_NAME_AT_OID,
            new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.PAGER_AT_OID, new TelephoneNumberAnonymizer() );
        attributeAnonymizers.put( SchemaConstants.POSTAL_ADDRESS_AT_OID,
            new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.PHOTO_AT_OID, new BinaryAnonymizer( binaryLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.SECRETARY_AT_OID,
            new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers
            .put( SchemaConstants.SEE_ALSO_AT_OID, new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.SN_AT_OID, new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.TELEPHONE_NUMBER_AT_OID,
            new TelephoneNumberAnonymizer( telephoneNumberLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.UID_AT_OID, new StringAnonymizer( stringLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.UID_NUMBER_AT_OID,
            new IntegerAnonymizer( integerLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.USER_CERTIFICATE_AT_OID,
            new BinaryAnonymizer( binaryLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.USER_PASSWORD_AT_OID,
            new BinaryAnonymizer( binaryLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.USER_PKCS12_AT_OID,
            new BinaryAnonymizer( binaryLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.USER_SMIME_CERTIFICATE_AT_OID,
            new BinaryAnonymizer( binaryLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.X500_UNIQUE_IDENTIFIER_AT_OID,
            new BinaryAnonymizer( binaryLatestValueMap ) );
        attributeAnonymizers.put( SchemaConstants.FACSIMILE_TELEPHONE_NUMBER_AT_OID,
            new TelephoneNumberAnonymizer( telephoneNumberLatestValueMap ) );
    }
    
    
    /**
     * Set the latest value map to a defined anonymizer - if it exists -.
     *
     * @param attributeType The AttributeType we are targetting
     * @param latestValueMap The latest value map for this attribute
     */
    public void setAttributeLatestValueMap( AttributeType attributeType, Map<Integer, ?> latestValueMap )
    {
        Anonymizer anonymizer = attributeAnonymizers.get( attributeType.getOid() );
        
        if ( anonymizer != null )
        {
            if ( attributeType.getSyntax().isHumanReadable() )
            {
                anonymizer.setLatestStringMap( latestValueMap );
            }
            else
            {
                anonymizer.setLatestBytesMap( latestValueMap );
            }
        }
    }
    
    
    /**
     * Add an attributeType that has to be anonymized
     *
     * @param attributeType the AttributeType that has to be anonymized
     * @throws LdapException If the attributeType cannot be added
     */
    public void addAnonAttributeType( AttributeType attributeType ) throws LdapException
    {
        schemaManager.add( attributeType );
        LdapSyntax syntax = attributeType.getSyntax();
        
        if ( syntax.isHumanReadable() )
        {
            if ( syntax.getOid().equals( SchemaConstants.INTEGER_SYNTAX ) )
            {
                attributeAnonymizers.put( attributeType.getOid(), new IntegerAnonymizer() );
            }
            else if ( syntax.getOid().equals( SchemaConstants.DIRECTORY_STRING_SYNTAX ) )
            {
                attributeAnonymizers.put( attributeType.getOid(), new StringAnonymizer() );
            }
            else if ( syntax.getOid().equals( SchemaConstants.TELEPHONE_NUMBER_SYNTAX ) )
            {
                attributeAnonymizers.put( attributeType.getOid(), new TelephoneNumberAnonymizer() );
            }
        }
        else
        {
            attributeAnonymizers.put( attributeType.getOid(), new BinaryAnonymizer() );
        }
    }
    
    
    /**
     * Add an attributeType that has to be anonymized, with its associated anonymizer.
     *
     * @param attributeType the AttributeType that has to be anonymized
     * @param anonymizer the instance of anonymizer to use with this AttributeType
     * @throws LdapException If the attributeType cannot be added
     */
    public void addAnonAttributeType( AttributeType attributeType, Anonymizer<?> anonymizer ) throws LdapException
    {
        schemaManager.add( attributeType );
        attributeAnonymizers.put( attributeType.getOid(), anonymizer );
    }
    
    
    /**
     * Remove an attributeType that has to be anonymized
     *
     * @param attributeType the AttributeType that we don't want to be anonymized
     */
    public void removeAnonAttributeType( AttributeType attributeType )
    {
        attributeAnonymizers.remove( attributeType.getOid() );
    }
    
    
    /**
     * @return The list of configured anonymizers
     */
    public Map<String, Anonymizer> getAttributeAnonymizers()
    {
        return attributeAnonymizers;
    }
    
    /**
     * Add a new NamingContext
     *
     * @param dn The naming context to add
     * @throws LdapInvalidDnException if it's an invalid naming context
     */
    public void addNamingContext( String dn ) throws LdapInvalidDnException
    {
        Dn namingContext = new Dn( schemaManager, dn );
        namingContexts.add( namingContext );
    }

    
    /**
     * Anonymize an AVA
     * 
     * @param ava The AVA to anonymize
     * @return The anonymized AVA
     * @throws LdapInvalidDnException If the Ava is invalid
     * @throws LdapInvalidAttributeValueException If teh Ava content is invalid
     */
    private Ava anonymizeAva( Ava ava ) throws LdapInvalidDnException, LdapInvalidAttributeValueException
    {
        Value value = ava.getValue();
        AttributeType attributeType = ava.getAttributeType();
        Value anonymizedValue = valueMap.get( value );
        Ava anonymizedAva;
        
        if ( anonymizedValue == null )
        {
            Attribute attribute = new DefaultAttribute( attributeType );
            attribute.add( value );
            Anonymizer anonymizer = attributeAnonymizers.get( attribute.getAttributeType().getOid() );

            if ( value.isHumanReadable() )
            {
                if ( anonymizer == null )
                {
                    anonymizedAva = new Ava( schemaManager, ava.getType(), value.getString() );
                }
                else
                {
                    Attribute anonymizedAttribute = anonymizer.anonymize( valueMap, valueSet, attribute );
                    anonymizedAva = new Ava( schemaManager, ava.getType(), anonymizedAttribute.getString() );
                }
            }
            else
            {
                if ( anonymizer == null )
                {
                    anonymizedAva = new Ava( schemaManager, ava.getType(), value.getBytes() );
                }
                else
                {
                    Attribute anonymizedAttribute = anonymizer.anonymize( valueMap, valueSet, attribute );

                    anonymizedAva = new Ava( schemaManager, ava.getType(), anonymizedAttribute.getBytes() );
                }
            }
        }
        else
        {
            if ( value.isHumanReadable() )
            {
                anonymizedAva = new Ava( schemaManager, ava.getType(), anonymizedValue.getString() );
            }
            else
            {
                anonymizedAva = new Ava( schemaManager, ava.getType(), anonymizedValue.getBytes() );
            }
        }

        return anonymizedAva;
    }
    
    
    /**
     * Anonymize the entry's DN
     * 
     * @param entryDn The DN to anonymize
     * @return The anonymized DN
     * @throws LdapException If the anonymization failed
     */
    private Dn anonymizeDn( Dn entryDn ) throws LdapException
    {
        // Search for the naming context
        Dn descendant = entryDn;
        Dn namingContext = null;
        
        for ( Dn nc : namingContexts )
        {
            if ( entryDn.isDescendantOf( nc ) )
            { 
                descendant = entryDn.getDescendantOf( nc );
                namingContext = nc;
                break;
            }
        }
        
        Rdn[] anonymizedRdns = new Rdn[entryDn.size()];
        int rdnPos = entryDn.size() - 1;

        if ( namingContext != null )
        {
            // Copy the naming contex
            for ( Rdn ncRdn : namingContext )
            {
                anonymizedRdns[rdnPos] = ncRdn;
                rdnPos--;
            }
        }
        
        // Iterate on all the RDN
        for ( Rdn rdn : descendant )
        {
            Ava[] anonymizedAvas = new Ava[rdn.size()];
            int pos = 0;
            
            // Iterate on the AVAs
            for ( Ava ava : rdn )
            {
                Ava anonymizedAva = anonymizeAva( ava );
                anonymizedAvas[pos] = anonymizedAva;
                pos++;
            }

            Rdn anonymizedRdn = new Rdn( schemaManager, anonymizedAvas );
            anonymizedRdns[rdnPos] = anonymizedRdn;
            rdnPos--;
        }
        
        return new Dn( schemaManager, anonymizedRdns );
    }


    /**
     * Anonymize a LDIF 
     * 
     * @param ldifFile The ldif file to anonymize
     * @param writer The Writer to use to write the result
     * @throws LdapException If we got some LDAP related exception
     * @throws IOException If we had some issue during some IO operations
     */
    public void anonymizeFile( String ldifFile, Writer writer ) throws LdapException, IOException
    {
        File inputFile = new File( ldifFile );
        
        if ( !inputFile.exists() )
        {
            println( "Cannot open file " + ldifFile );
            return;
        }
        
        try ( LdifReader ldifReader = new LdifReader( inputFile, schemaManager ) )
        {
            int count = 0;
            List<LdifEntry> errors = new ArrayList<>();
            List<String> errorTexts = new ArrayList<>();
    
            try
            {
                for ( LdifEntry ldifEntry : ldifReader )
                {
                    count++;
                    
                    try
                    {
                        if ( ldifEntry.isEntry() && !ldifEntry.isChangeAdd() )
                        {
                            // process a full entry. Add changes aren't processed here.
                            Entry newEntry = anonymizeEntry( ldifEntry );
                            
                            writer.write( LdifUtils.convertToLdif( newEntry ) );
                            writer.write( "\n" );
                        }
                        else if ( ldifEntry.isChangeDelete() )
                        {
                            // A Delete operation
                            LdifEntry newLdifEntry = anonymizeChangeDelete( ldifEntry );
    
                            if ( ldifEntry != null )
                            {
                                writer.write( newLdifEntry.toString() );
                                writer.write( "\n" );
                            }
                        }
                        else if ( ldifEntry.isChangeAdd() )
                        {
                            // A Add operation
                            LdifEntry newLdifEntry = anonymizeChangeAdd( ldifEntry );
    
                            if ( ldifEntry != null )
                            {
                                writer.write( newLdifEntry.toString() );
                                writer.write( "\n" );
                            }
                        }
                        else if ( ldifEntry.isChangeModify() )
                        {
                            // A Modify operation
                            LdifEntry newLdifEntry = anonymizeChangeModify( ldifEntry );
    
                            if ( ldifEntry != null )
                            {
                                writer.write( newLdifEntry.toString() );
                                writer.write( "\n" );
                            }
                        }
                        else if ( ldifEntry.isChangeModDn() ||  ldifEntry.isChangeModRdn() )
                        {
                            // A MODDN operation
                            LdifEntry newLdifEntry = anonymizeChangeModDn( ldifEntry );
    
                            if ( ldifEntry != null )
                            {
                                writer.write( newLdifEntry.toString() );
                                writer.write( "\n" );
                            }
                        }
    
                        System.out.print( '.' );
                        
                        if ( count % 100  == 0 )
                        {
                            println();
                        }
                    }
                    catch ( Exception e )
                    {
                        System.out.print( '*' );
    
                        if ( count % 100  == 0 )
                        {
                            println();
                        }
                        
                        errors.add( ldifEntry );
                        errorTexts.add( e.getMessage() );
                    }
                }
    
                println();
                
                if ( !errors.isEmpty() )
                {
                    println( "There are " + errors.size() + " bad entries" );
                    int i = 0;
                    
                    for ( LdifEntry ldifEntry : errors )
                    {
                        println( "---------------------------------------------------" );
                        println( "error : " + errorTexts.get( i ) );
                        println( ldifEntry.getDn().toString() );
                        i++;
                    }
                }
            }
            finally
            {
                println();
    
                if ( !errors.isEmpty() )
                {
                    println( "There are " + errors.size() + " bad entries" );
                }
                    
                println( "Nb entries : " + count ); 
            }
        }
    }
    
    
    /**
     * Anonymize a Modify change
     * 
     * @param ldifEntry The entry to anonymize
     * @return The anonymized entry
     * @throws LdapException If the anonymization failed
     */
    private LdifEntry anonymizeChangeModify( LdifEntry ldifEntry ) throws LdapException
    {
        Dn entryDn = ldifEntry.getDn();
        LdifEntry newLdifEntry = new LdifEntry( schemaManager );
        newLdifEntry.setChangeType( ChangeType.Modify );

        // Process the DN first
        Dn anonymizedDn = anonymizeDn( entryDn );
        
        newLdifEntry.setDn( anonymizedDn );
        
        // Now, process the entry's attributes
        for ( Modification modification : ldifEntry.getModifications() )
        {
            Attribute attribute = modification.getAttribute();
            AttributeType attributeType = schemaManager.getAttributeType( attribute.getId() );
            
            if ( attributeType == null )
            {
                System.out.println( "\nUnknown AttributeType : " + attribute.getId() + " for entry " + entryDn );
                
                return null;
            }
            
            attribute.apply( attributeType );
            
            // Deal with the special case of a DN syntax
            if ( attributeType.getSyntax().getSyntaxChecker() instanceof DnSyntaxChecker )
            {
                Value[] anonymizedValues = new Value[ attribute.size()];
                int pos = 0;
                
                for ( Value dnValue : modification.getAttribute() )
                {
                    Dn dn = new Dn( schemaManager, dnValue.getString() );
                    Dn newdDn = anonymizeDn( dn );
                    anonymizedValues[pos++] = new Value( newdDn.toString() );
                }
                
                Modification anonymizedModification = new DefaultModification( modification.getOperation(), attributeType, anonymizedValues );
                newLdifEntry.addModification( anonymizedModification );
            }
            else
            {
                Anonymizer anonymizer = attributeAnonymizers.get( attributeType.getOid() );

                if ( anonymizer == null )
                {
                    newLdifEntry.addModification( modification );
                }
                else
                {
                    Attribute anonymizedAttribute = anonymizer.anonymize( valueMap, valueSet, attribute );
                    
                    Modification anonymizedModification = new DefaultModification( modification.getOperation(), anonymizedAttribute );
                    newLdifEntry.addModification( anonymizedModification );
                }
            }
        }

        return newLdifEntry;
    }

    
    /**
     * Anonymize a Add change
     * 
     * @param ldifEntry The entry to anonymize
     * @return The anonymized entry
     * @throws LdapException If the anonymization failed
     */
    private LdifEntry anonymizeChangeAdd( LdifEntry ldifEntry ) throws LdapException
    {
        Dn entryDn = ldifEntry.getDn();
        LdifEntry newLdifEntry = new LdifEntry( schemaManager );
        newLdifEntry.setChangeType( ChangeType.Add );

        // Process the DN first
        Dn anonymizedDn = anonymizeDn( entryDn );
        
        newLdifEntry.setDn( anonymizedDn );
        
        // Now, process the entry's attributes
        for ( Attribute attribute : ldifEntry )
        {
            AttributeType attributeType = attribute.getAttributeType();
            Attribute anonymizedAttribute = new DefaultAttribute( attributeType );
            
            // Deal with the special case of a DN syntax
            
            if ( attributeType.getSyntax().getSyntaxChecker() instanceof DnSyntaxChecker )
            {
                for ( Value dnValue : attribute )
                {
                    Dn dn = new Dn( schemaManager, dnValue.getString() );
                    Dn newdDn = anonymizeDn( dn );
                    anonymizedAttribute.add( newdDn.toString() );
                }
                
                newLdifEntry.addAttribute( attribute );
            }
            else
            {
                Anonymizer anonymizer = attributeAnonymizers.get( attribute.getAttributeType().getOid() );

                if ( anonymizer == null )
                {
                    newLdifEntry.addAttribute( attribute );
                }
                else
                {
                    anonymizedAttribute = anonymizer.anonymize( valueMap, valueSet, attribute );
                    
                    if ( anonymizedAttribute != null )
                    {
                        newLdifEntry.addAttribute( anonymizedAttribute );
                    }
                }
            }
        }

        return newLdifEntry;
    }
    
    
    /**
     * Anonymize a Delete change
     * 
     * @param ldifEntry The entry to anonymize
     * @return The anonymized entry
     * @throws LdapException If the anonymization failed
     */
    private LdifEntry anonymizeChangeDelete( LdifEntry ldifEntry ) throws LdapException
    {
        Dn entryDn = ldifEntry.getDn();

        // Process the DN, there is nothing more in the entry
        Dn anonymizedDn = anonymizeDn( entryDn );
        
        ldifEntry.setDn( anonymizedDn );
        
        return ldifEntry;
    }
    
    
    /**
     * Anonymize a Delete change
     * 
     * @param ldifEntry The entry to anonymize
     * @return The anonymized entry
     * @throws LdapException If the anonymization failed
     */
    private LdifEntry anonymizeChangeModDn( LdifEntry ldifEntry ) throws LdapException
    {
        Dn entryDn = ldifEntry.getDn();

        // Process the DN
        Dn anonymizedDn = anonymizeDn( entryDn );
        
        ldifEntry.setDn( anonymizedDn );
        
        // Anonymize the newRdn if any
        String newRdnStr = ldifEntry.getNewRdn();
        
        if ( newRdnStr != null )
        {
            Dn newRdn = new Dn( schemaManager, newRdnStr );
            Dn anonymizedRdn = anonymizeDn( newRdn );
            
            ldifEntry.setNewRdn( anonymizedRdn.toString() );
        }
        
        // Anonymize the neSuperior if any
        String newSuperiorStr = ldifEntry.getNewSuperior();
        
        if ( newSuperiorStr != null )
        {
            Dn newSuperior = new Dn( schemaManager, newSuperiorStr );
            
            Dn anonymizedSuperior = anonymizeDn( newSuperior );
            
            ldifEntry.setNewSuperior( anonymizedSuperior.toString() );
        }

        return ldifEntry;
    }
    
    
    /**
     * Anonymize the full entry
     * 
     * @param ldifEntry The entry to anonymize
     * @return The anonymized entry
     * @throws LdapException If the anonymization failed
     */
    private Entry anonymizeEntry( LdifEntry ldifEntry ) throws LdapException
    {
        Entry entry = ldifEntry.getEntry();
        Entry newEntry = new DefaultEntry( schemaManager );

        // Process the DN first
        Dn entryDn = entry.getDn();
        
        Dn anonymizedDn = anonymizeDn( entryDn );
        
        // Now, process the entry's attributes
        for ( Attribute attribute : entry )
        {
            AttributeType attributeType = attribute.getAttributeType();
            
            // Deal with the special case of DN
            if ( attributeType.getSyntax().getSyntaxChecker() instanceof DnSyntaxChecker )
            {
                for ( Value dnValue : attribute )
                {
                    Dn dn = new Dn( schemaManager, dnValue.getString() );
                    Dn newdDn = anonymizeDn( dn );
                    newEntry.add( attributeType, newdDn.toString() );
                }
            }
            // Deal with the special case of a NameAndOptionalUID
            else if ( attributeType.getSyntax().getSyntaxChecker() instanceof NameAndOptionalUIDSyntaxChecker )
            {
                for ( Value dnValue : attribute )
                {
                    // Get rid of the # part (UID)
                    String valueStr = dnValue.getString();
                    int uidPos = valueStr.indexOf( '#' );
                    String uid = null;
                    
                    if ( uidPos != -1 )
                    {
                        uid = valueStr.substring( uidPos + 1 );
                        valueStr = valueStr.substring( 0, uidPos ); 
                    }
                    
                    Dn dn = new Dn( schemaManager, valueStr );
                    Dn newDn = anonymizeDn( dn );
                    String newDnStr = newDn.toString();
                    
                    if ( uid != null )
                    {
                        newDnStr = newDnStr + '#' + uid;
                    }
                    
                    newEntry.add( attributeType, newDnStr );
                }
            }
            else
            {
                Anonymizer anonymizer = attributeAnonymizers.get( attribute.getAttributeType().getOid() );

                if ( anonymizer == null )
                {
                    newEntry.add( attribute );
                }
                else
                {
                    Attribute anonymizedAttribute = anonymizer.anonymize( valueMap, valueSet, attribute );
                    
                    if ( anonymizedAttribute != null )
                    {
                        newEntry.add( anonymizedAttribute );
                    }
                }
            }
        }

        newEntry.setDn( anonymizedDn );

        return newEntry;
    }


    /**
     * Anonymize a LDIF 
     * 
     * @param ldif The ldif content to anonymize
     * @return an anonymized version of the given ldif
     * @throws LdapException If we got some LDAP related exception
     * @throws IOException If we had some issue during some IO operations
     */
    public String anonymize( String ldif ) throws LdapException, IOException
    {
        LdifReader ldifReader = new LdifReader( schemaManager );

        try
        {
            List<LdifEntry> entries = ldifReader.parseLdif( ldif );
            StringBuilder result = new StringBuilder();

            for ( LdifEntry ldifEntry : entries )
            {
                if ( ldifEntry.isEntry() && !ldifEntry.isChangeAdd() )
                {
                    // process a full entry. Add changes aren't preocessed ghere.
                    Entry newEntry = anonymizeEntry( ldifEntry );
                    
                    result.append( LdifUtils.convertToLdif( newEntry ) );
                    result.append( "\n" );
                }
                else if ( ldifEntry.isChangeDelete() )
                {
                    // A Delete operation
                    LdifEntry newLdifEntry = anonymizeChangeDelete( ldifEntry );

                    if ( newLdifEntry != null )
                    {
                        result.append( newLdifEntry );
                        result.append( "\n" );
                    }
                }
                else if ( ldifEntry.isChangeAdd() )
                {
                    // A Add operation
                    LdifEntry newLdifEntry = anonymizeChangeAdd( ldifEntry );

                    if ( newLdifEntry != null )
                    {
                        result.append( newLdifEntry );
                        result.append( "\n" );
                    }
                }
                else if ( ldifEntry.isChangeModify() )
                {
                    // A Modify operation
                    LdifEntry newLdifEntry = anonymizeChangeModify( ldifEntry );

                    if ( newLdifEntry != null )
                    {
                        result.append( newLdifEntry );
                        result.append( "\n" );
                    }
                }
                else if ( ldifEntry.isChangeModDn() ||  ldifEntry.isChangeModRdn() )
                {
                    // A MODDN operation
                    LdifEntry newLdifEntry = anonymizeChangeModDn( ldifEntry );

                    if ( newLdifEntry != null )
                    {
                        result.append( newLdifEntry );
                        result.append( "\n" );
                    }
                }
            }

            return result.toString();
        }
        catch ( Exception e )
        {
            println( "Error :"  + e.getMessage() );
            return null;
        }
        finally
        {
            ldifReader.close();
        }
    }


    /**
     * @return the valueMap
     */
    public Map<Value, Value> getValueMap()
    {
        return valueMap;
    }


    /**
     * @param valueMap the valueMap to set
     */
    public void setValueMap( Map<Value, Value> valueMap )
    {
        this.valueMap = valueMap;
    }


    /**
     * @return the latest String Value Map
     */
    public Map<Integer, String> getLatestStringMap()
    {
        return latestStringMap;
    }


    /**
     * @param latestStringMap the latest String Value Map to set
     */
    public void setLatestStringMap( Map<Integer, String> latestStringMap )
    {
        this.latestStringMap = latestStringMap;
    }


    /**
     * @return the latest byte[] Value Map
     */
    public Map<Integer, byte[]> getLatestBytesMap()
    {
        return latestBytesMap;
    }


    /**
     * @param latestBytesMap the latest byte[] Value Map to set
     */
    public void setLatestBytesMap( Map<Integer, byte[]> latestBytesMap )
    {
        this.latestBytesMap = latestBytesMap;
    }


    /**
     * The entry point, when used as a standalone application.
     *
     * @param args Contains the arguments : the file to convert. The anonymized 
     * LDIF will be printed on stdout
     * @throws IOException If we had an issue opening the file to anonymise ot writing the result
     * @throws LdapException If we had some issue while processing the LDAP data
     */
    public static void main( String[] args ) throws IOException, LdapException
    {
        if ( ( args == null ) || ( args.length < 1 ) )
        {
            System.out.println( "No file to anonymize" );
            return;
        }

        LdifAnonymizer anonymizer = new LdifAnonymizer();

        String ldifString = null;
        
        try ( InputStream fis = Files.newInputStream( Paths.get( args[0] ) ) )
        {
            try ( BufferedReader br = new BufferedReader( new InputStreamReader( fis, Charset.defaultCharset() ) ) )
            {
                StringBuilder sb = new StringBuilder();
                String line = br.readLine();
    
                while ( line != null )
                {
                    sb.append( line );
                    sb.append( System.lineSeparator() );
                    line = br.readLine();
                }

                ldifString = sb.toString();
            }
        }

        String result = anonymizer.anonymize( ldifString );

        System.out.println( result );
    }
}
