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

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.Entry;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.exception.LdapOtherException;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.api.ldap.model.schema.AttributeType;
import org.apache.directory.api.ldap.model.schema.DitContentRule;
import org.apache.directory.api.ldap.model.schema.DitStructureRule;
import org.apache.directory.api.ldap.model.schema.LdapComparator;
import org.apache.directory.api.ldap.model.schema.LdapSyntax;
import org.apache.directory.api.ldap.model.schema.MatchingRule;
import org.apache.directory.api.ldap.model.schema.MatchingRuleUse;
import org.apache.directory.api.ldap.model.schema.NameForm;
import org.apache.directory.api.ldap.model.schema.Normalizer;
import org.apache.directory.api.ldap.model.schema.ObjectClass;
import org.apache.directory.api.ldap.model.schema.SchemaManager;
import org.apache.directory.api.ldap.model.schema.SchemaObjectRenderer;
import org.apache.directory.api.ldap.model.schema.SchemaUtils;
import org.apache.directory.api.ldap.model.schema.SyntaxChecker;
import org.apache.directory.api.ldap.model.schema.registries.NormalizerRegistry;
import org.apache.directory.server.constants.ApacheSchemaConstants;
import org.apache.directory.server.constants.ServerDNConstants;
import org.apache.directory.server.core.api.DirectoryService;
import org.apache.directory.server.core.api.entry.ClonedServerEntry;
import org.apache.directory.server.core.api.interceptor.context.FilteringOperationContext;
import org.apache.directory.server.core.api.interceptor.context.LookupOperationContext;
import org.apache.directory.server.core.api.partition.Partition;
import org.apache.directory.server.core.api.partition.PartitionTxn;


/**
 * This class manage the Schema's operations. 
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public final class SchemaService
{
    /** cached version of the schema subentry with all attributes in it */
    private static Entry schemaSubentry;

    /** A lock to avid concurrent generation of the SubschemaSubentry */
    private static Object schemaSubentrLock = new Object();


    private SchemaService()
    {
    }


    /**
     * Generate the comparators attribute from the registry
     */
    private static Attribute generateComparators( SchemaManager schemaManager ) throws LdapException
    {
        Attribute attr = new DefaultAttribute(
            schemaManager.lookupAttributeTypeRegistry( SchemaConstants.COMPARATORS_AT ) );

        for ( LdapComparator<?> comparator : schemaManager.getComparatorRegistry() )
        {
            attr.add( SchemaUtils.render( comparator ) );
        }

        return attr;
    }


    private static Attribute generateNormalizers( SchemaManager schemaManager ) throws LdapException
    {
        Attribute attr = new DefaultAttribute(
            schemaManager.getAttributeType( SchemaConstants.NORMALIZERS_AT ) );

        NormalizerRegistry nr = schemaManager.getNormalizerRegistry();

        for ( Normalizer normalizer : nr )
        {
            attr.add( SchemaUtils.render( normalizer ) );
        }

        return attr;
    }


    private static Attribute generateSyntaxCheckers( SchemaManager schemaManager ) throws LdapException
    {
        Attribute attr = new DefaultAttribute(
            schemaManager.getAttributeType( SchemaConstants.SYNTAX_CHECKERS_AT ) );

        for ( SyntaxChecker syntaxChecker : schemaManager.getSyntaxCheckerRegistry() )
        {
            attr.add( SchemaUtils.render( syntaxChecker ) );
        }

        return attr;
    }


    private static Attribute generateObjectClasses( SchemaManager schemaManager ) throws LdapException
    {
        Attribute attr = new DefaultAttribute(
            schemaManager.getAttributeType( SchemaConstants.OBJECT_CLASSES_AT ) );

        for ( ObjectClass objectClass : schemaManager.getObjectClassRegistry() )
        {
            attr.add( SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( objectClass ) );
        }

        return attr;
    }


    private static Attribute generateAttributeTypes( SchemaManager schemaManager ) throws LdapException
    {
        Attribute attr = new DefaultAttribute(
            schemaManager.getAttributeType( SchemaConstants.ATTRIBUTE_TYPES_AT ) );

        for ( AttributeType attributeType : schemaManager.getAttributeTypeRegistry() )
        {
            attr.add( SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( attributeType ) );
        }

        return attr;
    }


    private static Attribute generateMatchingRules( SchemaManager schemaManager ) throws LdapException
    {
        Attribute attr = new DefaultAttribute(
            schemaManager.getAttributeType( SchemaConstants.MATCHING_RULES_AT ) );

        for ( MatchingRule matchingRule : schemaManager.getMatchingRuleRegistry() )
        {
            attr.add( SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( matchingRule ) );
        }

        return attr;
    }


    private static Attribute generateMatchingRuleUses( SchemaManager schemaManager ) throws LdapException
    {
        Attribute attr = new DefaultAttribute(
            schemaManager.getAttributeType( SchemaConstants.MATCHING_RULE_USE_AT ) );

        for ( MatchingRuleUse matchingRuleUse : schemaManager.getMatchingRuleUseRegistry() )
        {
            attr.add( SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( matchingRuleUse ) );
        }

        return attr;
    }


    private static Attribute generateSyntaxes( SchemaManager schemaManager ) throws LdapException
    {
        Attribute attr = new DefaultAttribute(
            schemaManager.getAttributeType( SchemaConstants.LDAP_SYNTAXES_AT ) );

        for ( LdapSyntax syntax : schemaManager.getLdapSyntaxRegistry() )
        {
            attr.add( SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( syntax ) );
        }

        return attr;
    }


    private static Attribute generateDitContextRules( SchemaManager schemaManager ) throws LdapException
    {
        Attribute attr = new DefaultAttribute(
            schemaManager.getAttributeType( SchemaConstants.DIT_CONTENT_RULES_AT ) );

        for ( DitContentRule ditContentRule : schemaManager.getDITContentRuleRegistry() )
        {
            attr.add( SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( ditContentRule ) );
        }

        return attr;
    }


    private static Attribute generateDitStructureRules( SchemaManager schemaManager ) throws LdapException
    {
        Attribute attr = new DefaultAttribute(
            schemaManager.getAttributeType( SchemaConstants.DIT_STRUCTURE_RULES_AT ) );

        for ( DitStructureRule ditStructureRule : schemaManager.getDITStructureRuleRegistry() )
        {
            attr.add( SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( ditStructureRule ) );
        }

        return attr;
    }


    private static Attribute generateNameForms( SchemaManager schemaManager ) throws LdapException
    {
        Attribute attr = new DefaultAttribute(
            schemaManager.getAttributeType( SchemaConstants.NAME_FORMS_AT ) );

        for ( NameForm nameForm : schemaManager.getNameFormRegistry() )
        {
            attr.add( SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( nameForm ) );
        }

        return attr;
    }


    /**
     * Creates the SSSE by extracting all the SchemaObjects from the registries.
     */
    private static void generateSchemaSubentry( SchemaManager schemaManager, Entry mods ) throws LdapException
    {
        Entry attrs = new DefaultEntry( schemaManager, mods.getDn() );

        // add the objectClass attribute : 'top', 'subschema', 'subentry' and 'apacheSubschema' 
        attrs.put( SchemaConstants.OBJECT_CLASS_AT,
            SchemaConstants.TOP_OC,
            SchemaConstants.SUBSCHEMA_OC,
            SchemaConstants.SUBENTRY_OC,
            ApacheSchemaConstants.APACHE_SUBSCHEMA_OC
            );

        // add the cn attribute as required for the Rdn
        attrs.put( SchemaConstants.CN_AT, "schema" );

        // generate all the other operational attributes
        attrs.put( generateComparators( schemaManager ) );
        attrs.put( generateNormalizers( schemaManager ) );
        attrs.put( generateSyntaxCheckers( schemaManager ) );
        attrs.put( generateObjectClasses( schemaManager ) );
        attrs.put( generateAttributeTypes( schemaManager ) );
        attrs.put( generateMatchingRules( schemaManager ) );
        attrs.put( generateMatchingRuleUses( schemaManager ) );
        attrs.put( generateSyntaxes( schemaManager ) );
        attrs.put( generateDitContextRules( schemaManager ) );
        attrs.put( generateDitStructureRules( schemaManager ) );
        attrs.put( generateNameForms( schemaManager ) );
        attrs.put( SchemaConstants.SUBTREE_SPECIFICATION_AT, "{}" );

        // -------------------------------------------------------------------
        // set standard operational attributes for the subentry
        // -------------------------------------------------------------------

        // Add the createTimestamp
        Attribute createTimestamp = mods.get( SchemaConstants.CREATE_TIMESTAMP_AT );
        attrs.put( SchemaConstants.CREATE_TIMESTAMP_AT, createTimestamp.get() );

        // Add the creatorsName
        attrs.put( SchemaConstants.CREATORS_NAME_AT, ServerDNConstants.ADMIN_SYSTEM_DN );

        // Add the modifyTimestamp
        Attribute schemaModifyTimestamp = mods.get( ApacheSchemaConstants.SCHEMA_MODIFY_TIMESTAMP_AT );
        attrs.put( SchemaConstants.MODIFY_TIMESTAMP_AT, schemaModifyTimestamp.get() );

        // Add the modifiersName
        Attribute schemaModifiersName = mods.get( ApacheSchemaConstants.SCHEMA_MODIFIERS_NAME_AT );
        attrs.put( SchemaConstants.MODIFIERS_NAME_AT, schemaModifiersName.get() );

        // don't swap out if a request for the subentry is in progress or we
        // can give back an inconsistent schema back to the client so we block
        synchronized ( schemaSubentrLock )
        {
            schemaSubentry = attrs;
        }
    }


    private static void addAttribute( Entry attrs, String id ) throws LdapException
    {
        Attribute attr = schemaSubentry.get( id );

        if ( ( attr != null ) && ( attr.size() > 0 ) )
        {
            attrs.put( attr );
        }
    }


    /**
     * {@inheritDoc}
     */
    public static Entry getSubschemaEntryImmutable( DirectoryService directoryService ) throws LdapException
    {
        synchronized ( schemaSubentrLock )
        {
            if ( schemaSubentry == null )
            {
                Dn schemaModificationAttributesDn = new Dn( directoryService.getSchemaManager(),
                    SchemaConstants.SCHEMA_MODIFICATIONS_DN );
                
                Partition partition = directoryService.getSchemaPartition();
                
                LookupOperationContext lookupContext = new LookupOperationContext( null, schemaModificationAttributesDn );
                lookupContext.setPartition( partition );

                try ( PartitionTxn partitionTxn = partition.beginReadTransaction() )
                {
                    lookupContext.setTransaction( partitionTxn );
                    
                    generateSchemaSubentry( directoryService.getSchemaManager(),
                        directoryService.getSchemaPartition().lookup( lookupContext ) );
                }
                catch ( IOException ioe )
                {
                    throw new LdapOtherException( ioe.getMessage(), ioe );
                }
            }

            return schemaSubentry.clone();
        }
    }


    /* (non-Javadoc)
     * @see org.apache.directory.server.core.schema.SchemaService#getSubschemaEntryCloned()
     */
    public static Entry getSubschemaEntryCloned( DirectoryService directoryService ) throws LdapException
    {
        if ( schemaSubentry == null )
        {
            Dn schemaModificationAttributesDn = new Dn( directoryService.getSchemaManager(),
                SchemaConstants.SCHEMA_MODIFICATIONS_DN );

            Partition partition = directoryService.getSchemaPartition();
            
            LookupOperationContext lookupContext = new LookupOperationContext( null, schemaModificationAttributesDn );
            lookupContext.setPartition( partition );

            try ( PartitionTxn partitionTxn = partition.beginReadTransaction() )
            {
                lookupContext.setTransaction( partitionTxn );
                
                generateSchemaSubentry(
                    directoryService.getSchemaManager(),
                    directoryService.getSchemaPartition().lookup( lookupContext ) );
            }
            catch ( IOException ioe )
            {
                throw new LdapOtherException( ioe.getMessage(), ioe );
            }
        }

        return schemaSubentry.clone();
    }


    /**
     * {@inheritDoc}
     */
    public static Entry getSubschemaEntry( DirectoryService directoryService, FilteringOperationContext operationContext )
        throws LdapException
    {
        SchemaManager schemaManager = directoryService.getSchemaManager();

        Entry attrs = new DefaultEntry( schemaManager, Dn.ROOT_DSE );

        synchronized ( schemaSubentrLock )
        {
            // ---------------------------------------------------------------
            // Check if we need an update by looking at timestamps on disk
            // ---------------------------------------------------------------
            Dn schemaModificationAttributesDn = new Dn( directoryService.getSchemaManager(),
                SchemaConstants.SCHEMA_MODIFICATIONS_DN );

            Partition partition = directoryService.getSchemaPartition();
            
            LookupOperationContext lookupContext = new LookupOperationContext( null, schemaModificationAttributesDn, SchemaConstants.ALL_ATTRIBUTES_ARRAY );
            lookupContext.setPartition( partition );

            try ( PartitionTxn partitionTxn = partition.beginReadTransaction() )
            {
                lookupContext.setTransaction( partitionTxn );

                Entry mods =
                    directoryService.getSchemaPartition().lookup( lookupContext );
                // TODO enable this optimization at some point but for now it
                // is causing some problems so I will just turn it off
                //          Attribute modifyTimeDisk = mods.get( SchemaConstants.MODIFY_TIMESTAMP_AT );
                //
                //          Attribute modifyTimeMemory = null;
                //
                //            if ( schemaSubentry != null )
                //            {
                //                modifyTimeMemory = schemaSubentry.get( SchemaConstants.MODIFY_TIMESTAMP_AT );
                //                if ( modifyTimeDisk == null && modifyTimeMemory == null )
                //                {
                //                    // do nothing!
                //                }
                //                else if ( modifyTimeDisk != null && modifyTimeMemory != null )
                //                {
                //                    Date disk = DateUtils.getDate( ( String ) modifyTimeDisk.get() );
                //                    Date mem = DateUtils.getDate( ( String ) modifyTimeMemory.get() );
                //                    if ( disk.after( mem ) )
                //                    {
                //                        generateSchemaSubentry( mods );
                //                    }
                //                }
                //                else
                //                {
                //                    generateSchemaSubentry( mods );
                //                }
                //            }
                //            else
                //            {
                generateSchemaSubentry( schemaManager, mods );
            }
            catch ( IOException ioe )
            {
                throw new LdapOtherException( ioe.getMessage(), ioe );
            }

            // ---------------------------------------------------------------
            // Prep Work: Transform the attributes to their OID counterpart
            // ---------------------------------------------------------------
            addAttribute( attrs, SchemaConstants.COMPARATORS_AT );
            addAttribute( attrs, SchemaConstants.NORMALIZERS_AT );
            addAttribute( attrs, SchemaConstants.SYNTAX_CHECKERS_AT );
            addAttribute( attrs, SchemaConstants.OBJECT_CLASSES_AT );
            addAttribute( attrs, SchemaConstants.ATTRIBUTE_TYPES_AT );
            addAttribute( attrs, SchemaConstants.MATCHING_RULES_AT );
            addAttribute( attrs, SchemaConstants.MATCHING_RULE_USE_AT );
            addAttribute( attrs, SchemaConstants.LDAP_SYNTAXES_AT );
            addAttribute( attrs, SchemaConstants.DIT_CONTENT_RULES_AT );
            addAttribute( attrs, SchemaConstants.DIT_STRUCTURE_RULES_AT );
            addAttribute( attrs, SchemaConstants.NAME_FORMS_AT );
            addAttribute( attrs, SchemaConstants.SUBTREE_SPECIFICATION_AT );

            // add the objectClass attribute if needed
            addAttribute( attrs, SchemaConstants.OBJECT_CLASS_AT );

            // add the cn attribute as required for the Rdn
            addAttribute( attrs, SchemaConstants.CN_AT );

            // -------------------------------------------------------------------
            // set standard operational attributes for the subentry
            // -------------------------------------------------------------------
            addAttribute( attrs, SchemaConstants.CREATE_TIMESTAMP_AT );
            addAttribute( attrs, SchemaConstants.CREATORS_NAME_AT );
            addAttribute( attrs, SchemaConstants.MODIFY_TIMESTAMP_AT );
            addAttribute( attrs, SchemaConstants.MODIFIERS_NAME_AT );
            addAttribute( attrs, SchemaConstants.ENTRY_UUID_AT );
            addAttribute( attrs, SchemaConstants.ENTRY_DN_AT );
        }

        return new ClonedServerEntry( attrs );
    }
}
