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


import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidObjectException;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;
import java.util.regex.Pattern;

import org.apache.directory.api.i18n.I18n;
import org.apache.directory.api.ldap.model.constants.SchemaConstants;
import org.apache.directory.api.ldap.model.csn.Csn;
import org.apache.directory.api.ldap.model.csn.CsnFactory;
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.ldif.LdapLdifException;
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.name.Dn;
import org.apache.directory.api.ldap.model.schema.SchemaManager;
import org.apache.directory.api.ldap.schemaextractor.SchemaLdifExtractor;
import org.apache.directory.api.ldap.schemaextractor.impl.DefaultSchemaLdifExtractor;
import org.apache.directory.api.ldap.schemaextractor.impl.ResourceMap;
import org.apache.directory.server.core.api.interceptor.context.AddOperationContext;
import org.apache.directory.server.core.api.interceptor.context.HasEntryOperationContext;
import org.apache.directory.server.core.api.partition.Partition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * An schema extractor that adds schema LDIF entries directly to the schema partition.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class SchemaLdifToPartitionExtractor implements SchemaLdifExtractor
{

    /** The base path. */
    private static final String BASE_PATH = "";

    /** The logger. */
    private static final Logger LOG = LoggerFactory.getLogger( SchemaLdifToPartitionExtractor.class );

    /**
     * The pattern to extract the schema from LDIF files.
     * java.util.regex.Pattern is immutable so only one instance is needed for all uses.
     */
    private static final Pattern EXTRACT_PATTERN = Pattern.compile( ".*schema" + "[/\\Q\\\\E]" + "ou=schema.*\\.ldif" );

    private final CsnFactory csnFactory = new CsnFactory( 0 );

    /** The extracted flag. */
    private boolean extracted;

    private final SchemaManager schemaManager;
    private final Partition partition;


    /**
     * Creates an extractor which adds schema LDIF entries directly to the schema partition.
     * The bootstrap schema manager must at least know the 'apachemeta' schema.
     *
     * @param schemaManager the bootstrap schema manager
     * @param partition the destination partition
     */
    public SchemaLdifToPartitionExtractor( SchemaManager schemaManager, Partition partition ) throws LdapException
    {
        this.schemaManager = schemaManager;
        this.partition = partition;

        Dn dn = new Dn( schemaManager, SchemaConstants.OU_SCHEMA );
        HasEntryOperationContext hasEntryContext = new HasEntryOperationContext( null, dn );
        if ( partition.hasEntry( hasEntryContext ) )
        {
            LOG.info( "Schema entry 'ou=schema' exists: extracted state set to true." );
            extracted = true;
        }
        else
        {
            LOG.info( "Schema entry 'ou=schema' does NOT exist: extracted state set to false." );
            extracted = false;
        }
    }


    /**
     * Gets whether or not the schema has already been added to the schema partition.
     *
     * @return true if schema has already been added to the schema partition
     */
    public boolean isExtracted()
    {
        return extracted;
    }


    /**
     * {@inheritDoc}
     */
    public void extractOrCopy( boolean overwrite ) throws IOException
    {
        Map<String, Boolean> resources = ResourceMap.getResources( EXTRACT_PATTERN );

        // must sort the map to ensure parent entries are added before children
        resources = new TreeMap<String, Boolean>( resources );

        if ( !extracted || overwrite )
        {
            for ( Map.Entry<String, Boolean> entry : resources.entrySet() )
            {
                if ( entry.getValue() )
                {
                    addFromClassLoader( entry.getKey() );
                }
                else
                {
                    File resource = new File( entry.getKey() );
                    addLdifFile( resource );
                }
            }

            extracted = true;
        }
    }


    /**
     * {@inheritDoc}
     */
    public void extractOrCopy() throws IOException
    {
        extractOrCopy( false );
    }


    /**
     * Adds an schema entry from an LDIF file.
     *
     * @param source the source file to copy
     * @throws IOException if there are IO errors or the source does not exist
     */
    private void addLdifFile( File source ) throws IOException
    {
        LOG.debug( "copyFile(): source = {}", source );

        if ( !source.getParentFile().exists() )
        {
            throw new FileNotFoundException( I18n.err( I18n.ERR_08002, source.getAbsolutePath() ) );
        }

        FileInputStream in = new FileInputStream( source );
        addFromStream( in, source.getAbsolutePath() );
    }


    /**
     * Adds an schema entry from a class loader resource.
     *
     * @param resource the LDIF schema resource
     * @throws IOException if there are IO errors
     */
    private void addFromClassLoader( String resource ) throws IOException
    {
        InputStream in = DefaultSchemaLdifExtractor.getUniqueResourceAsStream( resource,
            "LDIF file in schema repository" );
        addFromStream( in, resource );
    }


    /**
     * Adds an schema entry from the given stream to the schema partition
     *
     * @param in the input stream
     * @param source the source
     * @throws IOException signals that an I/O exception has occurred.
     */
    private void addFromStream( InputStream in, String source ) throws IOException
    {
        try
        {
            LdifReader ldifReader = new LdifReader( in );
            boolean first = true;
            LdifEntry ldifEntry = null;

            try
            {
                while ( ldifReader.hasNext() )
                {
                    if ( first )
                    {
                        ldifEntry = ldifReader.next();
    
                        if ( ldifEntry.get( SchemaConstants.ENTRY_UUID_AT ) == null )
                        {
                            // No UUID, let's create one
                            UUID entryUuid = UUID.randomUUID();
                            ldifEntry.addAttribute( SchemaConstants.ENTRY_UUID_AT, entryUuid.toString() );
                        }
                        if ( ldifEntry.get( SchemaConstants.ENTRY_CSN_AT ) == null )
                        {
                            // No CSN, let's create one
                            Csn csn = csnFactory.newInstance();
                            ldifEntry.addAttribute( SchemaConstants.ENTRY_CSN_AT, csn.toString() );
                        }
    
                        first = false;
                    }
                    else
                    {
                        // throw an exception : we should not have more than one entry per schema ldif file
                        String msg = I18n.err( I18n.ERR_08003, source );
                        LOG.error( msg );
                        throw new InvalidObjectException( msg );
                    }
                }
            }
            finally
            {
                ldifReader.close();
            }

            // inject the entry
            Entry entry = new DefaultEntry( schemaManager, ldifEntry.getEntry() );
            AddOperationContext addContext = new AddOperationContext( null, entry );
            partition.add( addContext );
        }
        catch ( LdapLdifException ne )
        {
            String msg = I18n.err( I18n.ERR_08004, source, ne.getLocalizedMessage() );
            LOG.error( msg );
            throw new InvalidObjectException( msg );
        }
        catch ( LdapException ne )
        {
            String msg = I18n.err( I18n.ERR_08004, source, ne.getLocalizedMessage() );
            LOG.error( msg );
            throw new InvalidObjectException( msg );
        }
    }

}
