package org.apache.maven.index;

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

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.Query;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.maven.index.context.ContextMemberProvider;
import org.apache.maven.index.context.DefaultIndexingContext;
import org.apache.maven.index.context.ExistingLuceneIndexMismatchException;
import org.apache.maven.index.context.IndexCreator;
import org.apache.maven.index.context.IndexUtils;
import org.apache.maven.index.context.IndexingContext;
import org.apache.maven.index.context.MergedIndexingContext;
import org.apache.maven.index.context.StaticContextMemberProvider;
import org.apache.maven.index.context.UnsupportedExistingLuceneIndexException;
import org.apache.maven.index.expr.SearchExpression;
import org.apache.maven.index.util.IndexCreatorSorter;
import org.codehaus.plexus.util.FileUtils;

/**
 * A default {@link NexusIndexer} implementation.
 *
 * @author Tamas Cservenak
 * @author Eugene Kuleshov
 * @deprecated Use {@link Indexer} instead. Discouraged from further use, as it suffers from multiple synchronization
 *             and other problems. As it tries to serve as "context registry" too, but it does not synchronize the
 *             access to it, but also, introduces some extras (like "targeted" vs "non targeted" search), that makes
 *             it's behavior less intuitive.
 */
@Deprecated
@Singleton
@Named
public class DefaultNexusIndexer
    extends ComponentSupport
    implements NexusIndexer
{

    private final Indexer indexer;

    private final Scanner scanner;

    private final IndexerEngine indexerEngine;

    private final QueryCreator queryCreator;

    private final Map<String, IndexingContext> indexingContexts = new ConcurrentHashMap<String, IndexingContext>();

    @Inject
    public DefaultNexusIndexer( final Indexer indexer, final Scanner scanner, final IndexerEngine indexerEngine,
        final QueryCreator queryCreator )
    {
        this.indexer = indexer;
        this.scanner = scanner;
        this.indexerEngine = indexerEngine;
        this.queryCreator = queryCreator;
    }

    // ----------------------------------------------------------------------------
    // Contexts
    // ----------------------------------------------------------------------------

    public void addIndexingContext( IndexingContext context )
    {
        indexingContexts.put( context.getId(), context );
    }

    ;
    public IndexingContext addIndexingContext( String id, String repositoryId, File repository, File indexDirectory,
        String repositoryUrl, String indexUpdateUrl,
        List<? extends IndexCreator> indexers )
        throws IOException, UnsupportedExistingLuceneIndexException
    {
        try
        {
            IndexingContext context =
                indexer.createIndexingContext( id, repositoryId, repository, indexDirectory, repositoryUrl,
                                               indexUpdateUrl, true, false, indexers );
            indexingContexts.put( context.getId(), context );
            return context;
        }
        catch ( ExistingLuceneIndexMismatchException e )
        {
            throw new UnsupportedExistingLuceneIndexException( e.getMessage(), e );
        }
    }

    public IndexingContext addIndexingContextForced( String id, String repositoryId, File repository,
        File indexDirectory, String repositoryUrl, String indexUpdateUrl,
        List<? extends IndexCreator> indexers )
        throws IOException
    {
        IndexingContext context =
            indexer.createIndexingContext( id, repositoryId, repository, indexDirectory, repositoryUrl, indexUpdateUrl,
                                           true, true, indexers );
        indexingContexts.put( context.getId(), context );
        return context;
    }

    public IndexingContext addIndexingContext( String id, String repositoryId, File repository, Directory directory,
        String repositoryUrl, String indexUpdateUrl,
        List<? extends IndexCreator> indexers )
        throws IOException, UnsupportedExistingLuceneIndexException
    {
        try
        {
            IndexingContext context =
                new DefaultIndexingContext( id, repositoryId, repository, directory, repositoryUrl, indexUpdateUrl,
                                            IndexCreatorSorter.sort( indexers ), false );
            indexingContexts.put( context.getId(), context );
            return context;
        }
        catch ( ExistingLuceneIndexMismatchException e )
        {
            throw new UnsupportedExistingLuceneIndexException( e.getMessage(), e );
        }
    }

    public IndexingContext addIndexingContextForced( String id, String repositoryId, File repository,
        Directory directory, String repositoryUrl, String indexUpdateUrl,
        List<? extends IndexCreator> indexers )
        throws IOException
    {
        IndexingContext context =
            new DefaultIndexingContext( id, repositoryId, repository, directory, repositoryUrl, indexUpdateUrl,
                                        IndexCreatorSorter.sort( indexers ), true );
        indexingContexts.put( context.getId(), context );
        return context;
    }

    public IndexingContext addMergedIndexingContext( String id, String repositoryId, File repository,
        File indexDirectory, boolean searchable,
        Collection<IndexingContext> contexts )
        throws IOException
    {
        return addMergedIndexingContext( id, repositoryId, repository, indexDirectory, searchable,
                                         new StaticContextMemberProvider( contexts ) );
    }

    public IndexingContext addMergedIndexingContext( String id, String repositoryId, File repository,
        File indexDirectory, boolean searchable,
        ContextMemberProvider membersProvider )
        throws IOException
    {
        IndexingContext context =
            indexer.createMergedIndexingContext( id, repositoryId, repository, indexDirectory, searchable,
                                                 membersProvider );
        indexingContexts.put( context.getId(), context );
        return context;
    }

    public IndexingContext addMergedIndexingContext( String id, String repositoryId, File repository,
        Directory indexDirectory, boolean searchable,
        Collection<IndexingContext> contexts )
        throws IOException
    {
        IndexingContext context =
            new MergedIndexingContext( id, repositoryId, repository, indexDirectory, searchable,
                                       new StaticContextMemberProvider( contexts ) );
        indexingContexts.put( context.getId(), context );
        return context;
    }

    public IndexingContext addMergedIndexingContext( String id, String repositoryId, File repository,
        Directory indexDirectory, boolean searchable,
        ContextMemberProvider membersProvider )
        throws IOException
    {
        IndexingContext context =
            new MergedIndexingContext( id, repositoryId, repository, indexDirectory, searchable, membersProvider );
        indexingContexts.put( context.getId(), context );
        return context;
    }

    public void removeIndexingContext( IndexingContext context, boolean deleteFiles )
        throws IOException
    {
        if ( indexingContexts.containsKey( context.getId() ) )
        {
            indexingContexts.remove( context.getId() );
            indexer.closeIndexingContext( context, deleteFiles );
        }
    }

    public Map<String, IndexingContext> getIndexingContexts()
    {
        return Collections.unmodifiableMap( indexingContexts );
    }

    // ----------------------------------------------------------------------------
    // Scanning
    // ----------------------------------------------------------------------------

    public void scan( final IndexingContext context )
        throws IOException
    {
        scan( context, null );
    }

    public void scan( final IndexingContext context, boolean update )
        throws IOException
    {
        scan( context, null, update );
    }

    public void scan( final IndexingContext context, final ArtifactScanningListener listener )
        throws IOException
    {
        scan( context, listener, false );
    }

    public void scan( final IndexingContext context, final ArtifactScanningListener listener, final boolean update )
        throws IOException
    {
        scan( context, null, listener, update );
    }

    /**
     * Uses {@link Scanner} to scan repository content. A {@link ArtifactScanningListener} is used to process found
     * artifacts and to add them to the index using
     * {@link NexusIndexer#artifactDiscovered(ArtifactContext, IndexingContext)}.
     *
     * @see DefaultScannerListener
     * @see #artifactDiscovered(ArtifactContext, IndexingContext)
     */
    public void scan( final IndexingContext context, final String fromPath, final ArtifactScanningListener listener,
        final boolean update )
        throws IOException
    {
        final File repositoryDirectory = context.getRepository();
        if ( repositoryDirectory == null )
        {
            // nothing to scan
            return;
        }

        if ( !repositoryDirectory.exists() )
        {
            throw new IOException( "Repository directory " + repositoryDirectory + " does not exist" );
        }

        // always use temporary context when reindexing
        final File tmpFile = File.createTempFile( context.getId() + "-tmp", "" );
        final File tmpDir = new File( tmpFile.getParentFile(), tmpFile.getName() + ".dir" );
        if ( !tmpDir.mkdirs() )
        {
            throw new IOException( "Cannot create temporary directory: " + tmpDir );
        }

        IndexingContext tmpContext = null;
        try
        {
            final FSDirectory directory = FSDirectory.open( tmpDir );
            if ( update )
            {
                IndexUtils.copyDirectory( context.getIndexDirectory(), directory );
            }
            tmpContext = new DefaultIndexingContext( context.getId() + "-tmp", //
                                                     context.getRepositoryId(), //
                                                     context.getRepository(), //
                                                     directory, //
                                                     context.getRepositoryUrl(), //
                                                     context.getIndexUpdateUrl(), //
                                                     context.getIndexCreators(), //
                                                     true );

            scanner.scan( new ScanningRequest( tmpContext, //
                                               new DefaultScannerListener( tmpContext, indexerEngine,
                                                                           update, listener ), fromPath ) );

            tmpContext.updateTimestamp( true );
            context.replace( tmpContext.getIndexDirectory() );
        }
        catch ( Exception ex )
        {
            throw (IOException) new IOException( "Error scanning context " + context.getId() + ": " + ex ).initCause(
                ex );
        }
        finally
        {
            if ( tmpContext != null )
            {
                tmpContext.close( true );
            }

            if ( tmpFile.exists() )
            {
                tmpFile.delete();
            }

            FileUtils.deleteDirectory( tmpDir );
        }
    }

    /**
     * Delegates to the {@link IndexerEngine} to add a new artifact to the index
     */
    public void artifactDiscovered( ArtifactContext ac, IndexingContext context )
        throws IOException
    {
        if ( ac != null )
        {
            indexerEngine.index( context, ac );
        }
    }

    // ----------------------------------------------------------------------------
    // Modifying
    // ----------------------------------------------------------------------------

    /**
     * Delegates to the {@link IndexerEngine} to update artifact to the index
     */
    public void addArtifactToIndex( ArtifactContext ac, IndexingContext context )
        throws IOException
    {
        indexer.addArtifactsToIndex( Collections.singleton( ac ), context );
    }

    public void addArtifactsToIndex( Collection<ArtifactContext> acs, IndexingContext context )
        throws IOException
    {
        indexer.addArtifactsToIndex( acs, context );
    }

    /**
     * Delegates to the {@link IndexerEngine} to remove artifact from the index
     */
    public void deleteArtifactFromIndex( ArtifactContext ac, IndexingContext context )
        throws IOException
    {
        indexer.deleteArtifactsFromIndex( Collections.singleton( ac ), context );
    }

    public void deleteArtifactsFromIndex( Collection<ArtifactContext> acs, IndexingContext context )
        throws IOException
    {
        indexer.deleteArtifactsFromIndex( acs, context );
    }

    // ----------------------------------------------------------------------------
    // Searching
    // ----------------------------------------------------------------------------

    public FlatSearchResponse searchFlat( FlatSearchRequest request )
        throws IOException
    {
        if ( request.getContexts().isEmpty() )
        {
            request.getContexts().addAll( getIndexingContexts().values() );
        }
        return indexer.searchFlat( request );
    }

    public IteratorSearchResponse searchIterator( IteratorSearchRequest request )
        throws IOException
    {
        if ( request.getContexts().isEmpty() )
        {
            request.getContexts().addAll( getIndexingContexts().values() );
        }
        return indexer.searchIterator( request );
    }

    public GroupedSearchResponse searchGrouped( GroupedSearchRequest request )
        throws IOException
    {
        if ( request.getContexts().isEmpty() )
        {
            request.getContexts().addAll( getIndexingContexts().values() );
        }
        return indexer.searchGrouped( request );
    }

    // ----------------------------------------------------------------------------
    // Query construction
    // ----------------------------------------------------------------------------

    @Deprecated
    public Query constructQuery( Field field, String query, SearchType type )
        throws IllegalArgumentException
    {
        try
        {
            return queryCreator.constructQuery( field, query, type );
        }
        catch ( ParseException e )
        {
            throw new IllegalArgumentException( e );
        }
    }

    public Query constructQuery( Field field, SearchExpression expression )
        throws IllegalArgumentException
    {
        return indexer.constructQuery( field, expression );
    }

    // ----------------------------------------------------------------------------
    // Identification
    // ----------------------------------------------------------------------------

    public Collection<ArtifactInfo> identify( Field field, String query )
        throws IllegalArgumentException, IOException
    {
        return identify( constructQuery( field, query, SearchType.EXACT ) );
    }

    public Collection<ArtifactInfo> identify( File artifact )
        throws IOException
    {
        return identify( artifact, indexingContexts.values() );
    }

    public Collection<ArtifactInfo> identify( File artifact, Collection<IndexingContext> contexts )
        throws IOException
    {
        return indexer.identify( artifact, contexts );
    }

    public Collection<ArtifactInfo> identify( Query query )
        throws IOException
    {
        return identify( query, indexingContexts.values() );
    }

    public Collection<ArtifactInfo> identify( Query query, Collection<IndexingContext> contexts )
        throws IOException
    {
        return indexer.identify( query, contexts );
    }
}
