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

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;

import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchResult;

import org.apache.directory.server.i18n.I18n;
import org.apache.directory.shared.ldap.model.constants.SchemaConstants;
import org.apache.directory.shared.ldap.model.entry.DefaultModification;
import org.apache.directory.shared.ldap.model.entry.DefaultEntryAttribute;
import org.apache.directory.shared.ldap.model.entry.DefaultEntry;
import org.apache.directory.shared.ldap.model.entry.Entry;
import org.apache.directory.shared.ldap.model.entry.Modification;
import org.apache.directory.shared.ldap.model.entry.ModificationOperation;
import org.apache.directory.shared.ldap.model.entry.Value;
import org.apache.directory.shared.ldap.model.entry.EntryAttribute;
import org.apache.directory.shared.ldap.model.exception.LdapException;
import org.apache.directory.shared.ldap.model.exception.LdapInvalidAttributeTypeException;
import org.apache.directory.shared.ldap.model.name.Dn;
import org.apache.directory.shared.ldap.model.schema.MutableAttributeTypeImpl;
import org.apache.directory.shared.ldap.model.schema.SchemaManager;
import org.apache.directory.shared.ldap.model.schema.SchemaUtils;
import org.apache.directory.shared.util.EmptyEnumeration;
import org.apache.directory.shared.util.Strings;

/**
 * A helper class used to manipulate Entries, Attributes and Values.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class ServerEntryUtils
{
    /**
     * Convert a ServerAttribute into a BasicAttribute. The Dn is lost
     * during this conversion, as the Attributes object does not store
     * this element.
     *
     * @return An instance of a AttributesImpl() object
     */
    public static Attribute toBasicAttribute( EntryAttribute entryAttribute )
    {
        MutableAttributeTypeImpl attributeType = entryAttribute.getAttributeType();
        
        Attribute attribute = new BasicAttribute( attributeType.getName() );
        
        for ( Value<?> value: entryAttribute )
        {
            attribute.add( value.get() );
        }
        
        return attribute;
    }
    
    
    /**
     * Convert a ServerEntry into a BasicAttributes. The Dn is lost
     * during this conversion, as the Attributes object does not store
     * this element.
     *
     * @return An instance of a AttributesImpl() object
     */
    public static Attributes toBasicAttributes( Entry entry )
    {
        if ( entry == null )
        {
            return null;
        }
        
        Attributes attributes = new BasicAttributes( true );

        for ( MutableAttributeTypeImpl attributeType:entry.getAttributeTypes() )
        {
            EntryAttribute attr = entry.get( attributeType );
            
            // Deal with a special case : an entry without any ObjectClass
            if ( attributeType.getOid().equals( SchemaConstants.OBJECT_CLASS_AT_OID ) && attr.size() == 0 )
            {
                // We don't have any objectClass, just dismiss this element
                continue;
            }
            
            attributes.put( toBasicAttribute( attr ) );
        }
        
        return attributes;
    }


    /**
     * Convert a BasicAttribute or a AttributeImpl to a ServerAtribute
     *
     * @param attribute the BasicAttributes or AttributesImpl instance to convert
     * @param attributeType
     * @return An instance of a ServerEntry object
     * 
     * @throws InvalidAttributeIdentifierException If we had an incorrect attribute
     */
    public static EntryAttribute toServerAttribute( Attribute attribute, MutableAttributeTypeImpl attributeType ) throws LdapInvalidAttributeTypeException
    {
        if ( attribute == null )
        {
            return null;
        }
        
        try 
        {
            EntryAttribute serverAttribute = new DefaultEntryAttribute( attributeType );
        
            for ( NamingEnumeration<?> values = attribute.getAll(); values.hasMoreElements(); )
            {
                Object value = values.nextElement();
                int nbAdded = 0;
                
                if ( value == null )
                {
                    continue;
                }
                
                if ( serverAttribute.isHR() )
                {
                    if ( value instanceof String )
                    {
                        nbAdded = serverAttribute.add( (String)value );
                    }
                    else if ( value instanceof byte[] )
                    {
                        nbAdded = serverAttribute.add( Strings.utf8ToString((byte[]) value) );
                    }
                    else
                    {
                        throw new LdapInvalidAttributeTypeException();
                    }
                }
                else
                {
                    if ( value instanceof String )
                    {
                        nbAdded = serverAttribute.add( Strings.getBytesUtf8((String) value) );
                    }
                    else if ( value instanceof byte[] )
                    {
                        nbAdded = serverAttribute.add( (byte[])value );
                    }
                    else
                    {
                        throw new LdapInvalidAttributeTypeException();
                    }
                }
                
                if ( nbAdded == 0 )
                {
                    throw new LdapInvalidAttributeTypeException();
                }
            }
            
            return serverAttribute;
        }
        catch ( NamingException ne )
        {
            throw new LdapInvalidAttributeTypeException();
        }
    }


    /**
     * Convert a BasicAttributes or a AttributesImpl to a ServerEntry
     *
     * @param attributes the BasicAttributes or AttributesImpl instance to convert
     * @param registries The registries, needed ro build a ServerEntry
     * @param dn The Dn which is needed by the ServerEntry
     * @return An instance of a ServerEntry object
     * 
     * @throws LdapInvalidAttributeTypeException If we get an invalid attribute
     */
    public static Entry toServerEntry( Attributes attributes, Dn dn, SchemaManager schemaManager )
            throws LdapInvalidAttributeTypeException
    {
        if ( attributes instanceof BasicAttributes )
        {
            try 
            {
                Entry entry = new DefaultEntry( schemaManager, dn );
    
                for ( NamingEnumeration<? extends Attribute> attrs = attributes.getAll(); attrs.hasMoreElements(); )
                {
                    Attribute attr = attrs.nextElement();

                    String attributeId = attr.getID();
                    String id = SchemaUtils.stripOptions( attributeId );
                    Set<String> options = SchemaUtils.getOptions( attributeId );
                    // TODO : handle options.
                    MutableAttributeTypeImpl attributeType = schemaManager.lookupAttributeTypeRegistry( id );
                    EntryAttribute serverAttribute = ServerEntryUtils.toServerAttribute( attr, attributeType );
                    
                    if ( serverAttribute != null )
                    {
                        entry.put( serverAttribute );
                    }
                }
                
                return entry;
            }
            catch ( LdapException ne )
            {
                throw new LdapInvalidAttributeTypeException( ne.getLocalizedMessage() );
            }
        }
        else
        {
            return null;
        }
    }


    /**
     * Gets the target entry as it would look after a modification operation 
     * was performed on it.
     * 
     * @param mod the modification
     * @param entry the source entry that is modified
     * @return the resultant entry after the modification has taken place
     * @throws LdapException if there are problems accessing attributes
     */
    public static Entry getTargetEntry( Modification mod, Entry entry, SchemaManager schemaManager ) throws LdapException
    {
        Entry targetEntry = ( Entry ) entry.clone();
        ModificationOperation modOp = mod.getOperation();
        String id = mod.getAttribute().getId();
        MutableAttributeTypeImpl attributeType = schemaManager.lookupAttributeTypeRegistry( id );
        
        switch ( modOp )
        {
            case REPLACE_ATTRIBUTE :
                targetEntry.put( mod.getAttribute() );
                break;
                
            case REMOVE_ATTRIBUTE :
                EntryAttribute toBeRemoved = mod.getAttribute();

                if ( toBeRemoved.size() == 0 )
                {
                    targetEntry.removeAttributes( id );
                }
                else
                {
                    EntryAttribute existing = targetEntry.get( id );

                    if ( existing != null )
                    {
                        for ( Value<?> value:toBeRemoved )
                        {
                            existing.remove( value );
                        }
                    }
                }
                break;
                
            case ADD_ATTRIBUTE :
                EntryAttribute combined = new DefaultEntryAttribute( id, attributeType );
                EntryAttribute toBeAdded = mod.getAttribute();
                EntryAttribute existing = entry.get( id );

                if ( existing != null )
                {
                    for ( Value<?> value:existing )
                    {
                        combined.add( value );
                    }
                }

                for ( Value<?> value:toBeAdded )
                {
                    combined.add( value );
                }
                
                targetEntry.put( combined );
                break;
                
            default:
                throw new IllegalStateException( I18n.err( I18n.ERR_464, modOp ) );
        }

        return targetEntry;
    }


    /**
     * Creates a new attribute which contains the values representing the union
     * of two attributes. If one attribute is null then the resultant attribute
     * returned is a copy of the non-null attribute. If both are null then we
     * cannot determine the attribute ID and an {@link IllegalArgumentException}
     * is raised.
     * 
     * @param attr0 the first attribute
     * @param attr1 the second attribute
     * @return a new attribute with the union of values from both attribute
     *         arguments
     * @throws LdapException if there are problems accessing attribute values
     */
    public static EntryAttribute getUnion( EntryAttribute attr0, EntryAttribute attr1 )
    {
        if ( attr0 == null && attr1 == null )
        {
            throw new IllegalArgumentException( I18n.err( I18n.ERR_465 ) );
        }
        else if ( attr0 == null )
        {
            return attr1.clone();
        }
        else if ( attr1 == null )
        {
            return attr0.clone();
        }
        else if ( !attr0.getAttributeType().equals( attr1.getAttributeType() ) )
        {
            throw new IllegalArgumentException( I18n.err( I18n.ERR_466 ) );
        }

        EntryAttribute attr = attr0.clone();

        for ( Value<?> value:attr1 )
        {
            attr.add( value );
        }

        return attr;
    }
    
    
    /**
     * Convert a ModificationItem to an instance of a ServerModification object
     *
     * @param modificationImpl the modification instance to convert
     * @param attributeType the associated attributeType
     * @return a instance of a ServerModification object
     */
    private static Modification toServerModification( ModificationItem modificationImpl, MutableAttributeTypeImpl attributeType ) throws LdapInvalidAttributeTypeException

    {
        ModificationOperation operation;
        
        switch ( modificationImpl.getModificationOp() )
        {
            case DirContext.REMOVE_ATTRIBUTE :
                operation = ModificationOperation.REMOVE_ATTRIBUTE;
                break;
                
            case DirContext.REPLACE_ATTRIBUTE :
                operation = ModificationOperation.REPLACE_ATTRIBUTE;
                break;

            case DirContext.ADD_ATTRIBUTE :
            default :
                operation = ModificationOperation.ADD_ATTRIBUTE;
                break;
                
        }
        
        Modification modification = new DefaultModification( 
            operation,
            ServerEntryUtils.toServerAttribute( modificationImpl.getAttribute(), attributeType ) ); 
        
        return modification;
        
    }

    
    /**
     * 
     * Convert a list of ModificationItemImpl to a list of 
     *
     * @param modificationImpls
     * @param atRegistry
     * @return
     * @throws LdapException
     */
    public static List<Modification> convertToServerModification( List<ModificationItem> modificationItems, 
        SchemaManager schemaManager ) throws LdapException
    {
        if ( modificationItems != null )
        {
            List<Modification> modifications = new ArrayList<Modification>( modificationItems.size() );

            for ( ModificationItem modificationItem: modificationItems )
            {
                MutableAttributeTypeImpl attributeType = schemaManager.lookupAttributeTypeRegistry( modificationItem.getAttribute().getID() );
                modifications.add( toServerModification( modificationItem, attributeType ) );
            }
        
            return modifications;
        }
        else
        {
            return null;
        }
    }
    
    
    /**
     * Convert a Modification to an instance of a ServerModification object.
     *
     * @param modificationImpl the modification instance to convert
     * @param attributeType the associated attributeType
     * @return a instance of a ServerModification object
     */
    private static Modification toServerModification( Modification modification, MutableAttributeTypeImpl attributeType ) 
    {
        Modification serverModification = new DefaultModification( 
            modification.getOperation(),
            new DefaultEntryAttribute( attributeType, modification.getAttribute() ) ); 
        
        return serverModification;
        
    }

    
    public static List<Modification> toServerModification( Modification[] modifications, 
        SchemaManager schemaManager ) throws LdapException
    {
        if ( modifications != null )
        {
            List<Modification> modificationsList = new ArrayList<Modification>();
    
            for ( Modification modification: modifications )
            {
                String attributeId = modification.getAttribute().getId();
                String id = stripOptions( attributeId );
                modification.getAttribute().setId( id );
                Set<String> options = getOptions( attributeId );

                // -------------------------------------------------------------------
                // DIRSERVER-646 Fix: Replacing an unknown attribute with no values 
                // (deletion) causes an error
                // -------------------------------------------------------------------
                if ( ! schemaManager.getAttributeTypeRegistry().contains( id ) 
                     && modification.getAttribute().size() == 0 
                     && modification.getOperation() == ModificationOperation.REPLACE_ATTRIBUTE )
                {
                    // The attributeType does not exist in the schema.
                    // It's an error
                    String message = I18n.err( I18n.ERR_467, id );
                    throw new LdapInvalidAttributeTypeException( message );
                }
                else
                {
                    // TODO : handle options
                    MutableAttributeTypeImpl attributeType = schemaManager.lookupAttributeTypeRegistry( id );
                    modificationsList.add( toServerModification( modification, attributeType ) );
                }
            }
        
            return modificationsList;
        }
        else
        {
            return null;
        }
    }


    public static List<Modification> toServerModification( ModificationItem[] modifications, 
        SchemaManager schemaManager ) throws LdapException
    {
        if ( modifications != null )
        {
            List<Modification> modificationsList = new ArrayList<Modification>();
    
            for ( ModificationItem modification: modifications )
            {
                String attributeId = modification.getAttribute().getID();
                String id = stripOptions( attributeId );
                Set<String> options = getOptions( attributeId );

                // -------------------------------------------------------------------
                // DIRSERVER-646 Fix: Replacing an unknown attribute with no values 
                // (deletion) causes an error
                // -------------------------------------------------------------------
                
                // TODO - after removing JNDI we need to make the server handle 
                // this in the codec
                
                if ( ! schemaManager.getAttributeTypeRegistry().contains( id ) 
                     && modification.getAttribute().size() == 0 
                     && modification.getModificationOp() == DirContext.REPLACE_ATTRIBUTE )
                {
                    continue;
                }

                // -------------------------------------------------------------------
                // END DIRSERVER-646 Fix
                // -------------------------------------------------------------------
                
                
                // TODO : handle options
                MutableAttributeTypeImpl attributeType = schemaManager.lookupAttributeTypeRegistry( id );
                modificationsList.add( toServerModification( (ModificationItem)modification, attributeType ) );
            }
        
            return modificationsList;
        }
        else
        {
            return null;
        }
    }


    /**
     * Utility method to extract a modification item from an array of modifications.
     * 
     * @param mods the array of ModificationItems to extract the Attribute from.
     * @param type the attributeType spec of the Attribute to extract
     * @return the modification item on the attributeType specified
     */
    public static final Modification getModificationItem( List<Modification> mods, MutableAttributeTypeImpl type )
    {
        for ( Modification modification:mods )
        {
            EntryAttribute attribute = modification.getAttribute();
            
            if ( attribute.getAttributeType() == type )
            {
                return modification;
            }
        }
        
        return null;
    }
    
    
    /**
     * Utility method to extract an attribute from a list of modifications.
     * 
     * @param mods the list of ModificationItems to extract the Attribute from.
     * @param type the attributeType spec of the Attribute to extract
     * @return the extract Attribute or null if no such attribute exists
     */
    public static EntryAttribute getAttribute( List<Modification> mods, MutableAttributeTypeImpl type )
    {
        Modification mod = getModificationItem( mods, type );
        
        if ( mod != null )
        {
            return mod.getAttribute();
        }
        
        return null;
    }
    
    
    /**
     * Encapsulate a ServerSearchResult enumeration into a SearchResult enumeration
     * @param result The ServerSearchResult enumeration
     * @return A SearchResultEnumeration
     */
    public static NamingEnumeration<SearchResult> toSearchResultEnum( final NamingEnumeration<ServerSearchResult> result )
    {
        if ( result instanceof EmptyEnumeration<?> )
        {
            return new EmptyEnumeration<SearchResult>();
        }
        
        return new NamingEnumeration<SearchResult> ()
        {
            public void close() throws NamingException
            {
                result.close();
            }


            /**
             * @see javax.naming.NamingEnumeration#hasMore()
             */
            public boolean hasMore() throws NamingException
            {
                return result.hasMore();
            }


            /**
             * @see javax.naming.NamingEnumeration#next()
             */
            public SearchResult next() throws NamingException
            {
                ServerSearchResult rec = result.next();
                
                SearchResult searchResult = new SearchResult( 
                        rec.getDn().getName(), 
                        rec.getObject(), 
                        toBasicAttributes( rec.getServerEntry() ), 
                        rec.isRelative() );
                
                return searchResult;
            }
            
            
            /**
             * @see java.util.Enumeration#hasMoreElements()
             */
            public boolean hasMoreElements()
            {
                return result.hasMoreElements();
            }


            /**
             * @see java.util.Enumeration#nextElement()
             */
            public SearchResult nextElement()
            {
                try
                {
                    ServerSearchResult rec = result.next();
    
                    SearchResult searchResult = new SearchResult( 
                            rec.getDn().getName(), 
                            rec.getObject(), 
                            toBasicAttributes( rec.getServerEntry() ), 
                            rec.isRelative() );
                    
                    return searchResult;
                }
                catch ( NamingException ne )
                {
                    NoSuchElementException nsee = 
                        new NoSuchElementException( I18n.err( I18n.ERR_468 ) );
                    nsee.initCause( ne );
                    throw nsee;
                }
            }
        };
    }
    
    
    /**
     * Remove the options from the attributeType, and returns the ID.
     * 
     * RFC 4512 :
     * attributedescription = attributetype options
     * attributetype = oid
     * options = *( SEMI option )
     * option = 1*keychar
     */
    private static String stripOptions( String attributeId )
    {
        int optionsPos = attributeId.indexOf( ";" ); 
        
        if ( optionsPos != -1 )
        {
            return attributeId.substring( 0, optionsPos );
        }
        else
        {
            return attributeId;
        }
    }
    

    /**
     * Get the options from the attributeType.
     * 
     * For instance, given :
     * jpegphoto;binary;lang=jp
     * 
     * your get back a set containing { "binary", "lang=jp" }
     */
    private static Set<String> getOptions( String attributeId )
    {
        int optionsPos = attributeId.indexOf( ";" ); 

        if ( optionsPos != -1 )
        {
            Set<String> options = new HashSet<String>();
            
            String[] res = attributeId.substring( optionsPos + 1 ).split( ";" );
            
            for ( String option:res )
            {
                if ( !Strings.isEmpty(option) )
                {
                    options.add( option );
                }
            }
            
            return options;
        }
        else
        {
            return null;
        }
    }
}
