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 javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.Query;
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.IndexingContext;
import org.apache.maven.index.context.MergedIndexingContext;
import org.apache.maven.index.expr.SearchExpression;
import org.apache.maven.index.expr.SourcedSearchExpression;
import org.apache.maven.index.util.IndexCreatorSorter;
import org.codehaus.plexus.util.IOUtil;

/**
 * A default {@link Indexer} implementation.
 * 
 * @author Tamas Cservenak
 */
@Singleton
@Named
public class DefaultIndexer
    implements Indexer
{

    private final SearchEngine searcher;

    private final IndexerEngine indexerEngine;

    private final QueryCreator queryCreator;


    @Inject
    public DefaultIndexer( SearchEngine searcher,
                           IndexerEngine indexerEngine,
                           QueryCreator queryCreator )
    {
        this.searcher = searcher;
        this.indexerEngine = indexerEngine;
        this.queryCreator = queryCreator;
    }

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

    public IndexingContext createIndexingContext( String id, String repositoryId, File repository, File indexDirectory,
                                                  String repositoryUrl, String indexUpdateUrl, boolean searchable,
                                                  boolean reclaim, List<? extends IndexCreator> indexers )
        throws IOException, ExistingLuceneIndexMismatchException, IllegalArgumentException
    {
        final IndexingContext context =
            new DefaultIndexingContext( id, repositoryId, repository, indexDirectory, repositoryUrl, indexUpdateUrl,
                IndexCreatorSorter.sort( indexers ), reclaim );
        context.setSearchable( searchable );
        return context;
    }

    public IndexingContext createMergedIndexingContext( String id, String repositoryId, File repository,
                                                        File indexDirectory, boolean searchable,
                                                        ContextMemberProvider membersProvider )
        throws IOException
    {
        IndexingContext context =
            new MergedIndexingContext( id, repositoryId, repository, indexDirectory, searchable, membersProvider );
        return context;
    }

    public void closeIndexingContext( IndexingContext context, boolean deleteFiles )
        throws IOException
    {
        context.close( deleteFiles );
    }

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

    public void addArtifactsToIndex( Collection<ArtifactContext> ac, IndexingContext context )
        throws IOException
    {
        if ( ac != null && !ac.isEmpty() )
        {
            for ( ArtifactContext actx : ac )
            {
                indexerEngine.update( context, actx );
            }

            context.commit();
        }
    }

    public void deleteArtifactsFromIndex( Collection<ArtifactContext> ac, IndexingContext context )
        throws IOException
    {
        if ( ac != null && !ac.isEmpty() )
        {
            for ( ArtifactContext actx : ac )
            {
                indexerEngine.remove( context, actx );

                context.commit();
            }
        }
    }

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

    public FlatSearchResponse searchFlat( FlatSearchRequest request )
        throws IOException
    {
        if ( request.getContexts().isEmpty() )
        {
            return new FlatSearchResponse( request.getQuery(), 0, Collections.<ArtifactInfo> emptySet() );
        }
        else
        {
            return searcher.forceSearchFlatPaged( request, request.getContexts() );
        }
    }

    public IteratorSearchResponse searchIterator( IteratorSearchRequest request )
        throws IOException
    {
        if ( request.getContexts().isEmpty() )
        {
            return IteratorSearchResponse.empty( request.getQuery() );
        }
        else
        {
            return searcher.forceSearchIteratorPaged( request, request.getContexts() );
        }
    }

    public GroupedSearchResponse searchGrouped( GroupedSearchRequest request )
        throws IOException
    {
        if ( request.getContexts().isEmpty() )
        {
            return new GroupedSearchResponse( request.getQuery(), 0, Collections.<String, ArtifactInfoGroup> emptyMap() );
        }
        else
        {
            // search targeted
            return searcher.forceSearchGrouped( request, request.getContexts() );
        }
    }

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

    public Collection<ArtifactInfo> identify( final File artifact, final Collection<IndexingContext> contexts )
        throws IOException
    {
        try (FileInputStream is = new FileInputStream( artifact ))
        {
            final MessageDigest sha1 = MessageDigest.getInstance( "SHA-1" );
            final byte[] buff = new byte[4096];
            int n;
            while ( ( n = is.read( buff ) ) > -1 )
            {
                sha1.update( buff, 0, n );
            }
            byte[] digest = sha1.digest();
            return identify( constructQuery( MAVEN.SHA1, new SourcedSearchExpression( encode( digest ) ) ), contexts );
        }
        catch ( NoSuchAlgorithmException ex )
        {
            IOException ioe = new IOException( "Unable to calculate digest" );
            ioe.initCause( ex );
            throw ioe;
        }
    }

    public Collection<ArtifactInfo> identify( Query query, Collection<IndexingContext> contexts )
        throws IOException
    {
        final IteratorSearchResponse result =
            searcher.searchIteratorPaged( new IteratorSearchRequest( query ), contexts );
        try
        {
            final ArrayList<ArtifactInfo> ais = new ArrayList<ArtifactInfo>( result.getTotalHitsCount() );
            for ( ArtifactInfo ai : result )
            {
                ais.add( ai );
            }
            return ais;
        }
        finally
        {
            result.close();
        }
    }

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

    public Query constructQuery( Field field, SearchExpression expression )
        throws IllegalArgumentException
    {
        try
        {
            return queryCreator.constructQuery( field, expression );
        }
        catch ( ParseException e )
        {
            throw new IllegalArgumentException( e );
        }
    }

    // ==

    private static final char[] DIGITS = "0123456789abcdef".toCharArray();

    private static String encode( byte[] digest )
    {
        char[] buff = new char[digest.length * 2];

        int n = 0;

        for ( byte b : digest )
        {
            buff[n++] = DIGITS[( 0xF0 & b ) >> 4];
            buff[n++] = DIGITS[0x0F & b];
        }

        return new String( buff );
    }
}
