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


import java.util.Comparator;
import java.util.TreeSet;

import org.apache.directory.api.ldap.model.entry.Attribute;
import org.apache.directory.api.ldap.model.entry.Entry;
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.schema.AttributeType;
import org.apache.directory.api.ldap.model.schema.LdapComparator;
import org.apache.directory.api.ldap.model.schema.MatchingRule;
import org.apache.directory.api.ldap.model.schema.SchemaManager;

/**
 * A comparator to sort the entries as per <a href="http://tools.ietf.org/html/rfc2891">RFC 2891</a>
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
class SortedEntryComparator implements Comparator<Entry>
{

    /** the attribute's type */
    private AttributeType type;

    /** comparator used for comparing the values of the given attribute type */
    private Comparator comparator;

    /** flag to indicate if the attribute type is multivalued */
    private boolean multivalued;

    /** flag for indicating the order of sorting */
    private boolean reverse;

    /** flag to indicate if the attribute is human readable or binary */
    private boolean hr;


    /**
     * 
     * Creates a new instance of SortedEntryComparator.
     *
     * @param at the attribute's type
     * @param mrOid the OID or name of the matchingrule
     * @param reverse flag to indicate the sort order
     */
    public SortedEntryComparator( AttributeType at, String mrule, boolean reverse, SchemaManager schemaManager ) throws LdapException
    {
        this.type = at;
        this.reverse = reverse;

        if ( !at.isSingleValued() )
        {
            multivalued = true;
        }

        hr = at.getSyntax().isHumanReadable();

        if( mrule != null )
        {
            comparator = schemaManager.lookupComparatorRegistry( mrule );
        }
        else
        {
            MatchingRule mr = at.getOrdering();
            
            if( mr == null )
            {
                mr = at.getEquality();
            }
            
            comparator = schemaManager.lookupComparatorRegistry( mr.getOid() );
        }
        
        ( ( LdapComparator ) comparator ).setSchemaManager( schemaManager );
    }


    @Override
    public int compare( Entry entry1, Entry entry2 )
    {
        Attribute at1 = entry1.get( type );

        Attribute at2 = entry2.get( type );

        // as per section 2.2 of the spec null values are considered larger
        if ( at1 == null )
        {
            return ( reverse ? -1 : 1 );
        }
        else if ( at2 == null )
        {
            return ( reverse ? 1 : -1 );
        }

        Object o1 = null;
        Object o2 = null;

        if ( multivalued )
        {
            TreeSet ts = new TreeSet( comparator );

            o1 = sortAndGetFirst( at1, ts );

            ts.clear();
            o2 = sortAndGetFirst( at2, ts );
        }
        else
        {
            Value<?> v1 = at1.get();
            Value<?> v2 = at2.get();

            if ( hr )
            {
                o1 = v1.getString();
                o2 = v2.getString();
            }
            else
            {
                o1 = v1.getBytes();
                o2 = v2.getBytes();
            }
        }

        if( o1 == null || o2 == null )
        {
            System.out.println("");
        }
        int c = 1;

        if ( reverse )
        {
            c = comparator.compare( o2, o1 );
        }
        else
        {
            c = comparator.compare( o1, o2 );
        }

        if ( c == 0 )
        {
            return 1;
        }

        return c;
    }


    /**
     * sorts the values of an attribute and picks the least value
     * 
     * @param at the attribute
     * @param ts the TreeSet for sorting 
     * @return the least value among the values of the attribute
     */
    private Object sortAndGetFirst( Attribute at, TreeSet ts )
    {
        for ( Value v : at )
        {
            if ( hr )
            {
                ts.add( v.getString() );
            }
            else
            {
                ts.add( v.getBytes() );
            }
        }

        return ts.first();
    }
}