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.Named;
import javax.inject.Singleton;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.maven.index.context.IndexingContext;
import org.apache.maven.index.creator.MinimalArtifactInfoIndexCreator;

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

    public void index( IndexingContext context, ArtifactContext ac )
        throws IOException
    {
        // skip artifacts not obeying repository layout (whether m1 or m2)
        if ( ac != null && ac.getGav() != null )
        {
            Document d = ac.createDocument( context );

            if ( d != null )
            {
                context.getIndexWriter().addDocument( d );

                context.updateTimestamp();
            }
        }
    }

    public void update( IndexingContext context, ArtifactContext ac )
        throws IOException
    {
        if ( ac != null && ac.getGav() != null )
        {
            Document d = ac.createDocument( context );

            if ( d != null )
            {
                Document old = getOldDocument( context, ac );

                if ( !equals( d, old ) )
                {
                    IndexWriter w = context.getIndexWriter();

                    w.updateDocument( new Term( ArtifactInfo.UINFO, ac.getArtifactInfo().getUinfo() ), d );

                    updateGroups( context, ac );

                    context.updateTimestamp();
                }
            }
        }
    }

    public void remove( IndexingContext context, ArtifactContext ac )
        throws IOException
    {
        if ( ac != null )
        {
            final String uinfo = ac.getArtifactInfo().getUinfo();

            // add artifact deletion marker
            final Document doc = new Document();

            doc.add( new Field( ArtifactInfo.DELETED, uinfo, Field.Store.YES, Field.Index.NO ) );
            doc.add( new Field( ArtifactInfo.LAST_MODIFIED, //
                Long.toString( System.currentTimeMillis() ), Field.Store.YES, Field.Index.NO ) );

            IndexWriter w = context.getIndexWriter();
            w.addDocument( doc );
            w.deleteDocuments( new Term( ArtifactInfo.UINFO, uinfo ) );
            context.updateTimestamp();
        }
    }

    // ==

    private boolean equals( final Document d1, final Document d2 )
    {
        if ( d1 == null && d2 == null )
        {
            return true;
        }
        if ( d1 == null || d2 == null )
        {
            return false;
        }

        final Map<String, String> m1 = toMap( d1 );
        final Map<String, String> m2 = toMap( d2 );

        m1.remove( MinimalArtifactInfoIndexCreator.FLD_LAST_MODIFIED.getKey() );
        m2.remove( MinimalArtifactInfoIndexCreator.FLD_LAST_MODIFIED.getKey() );

        return m1.equals( m2 );
    }

    private Map<String, String> toMap( Document d )
    {
        final HashMap<String, String> result = new HashMap<String, String>();

        for ( Object o : d.getFields() )
        {
            IndexableField f = (IndexableField) o;
            if ( f.fieldType().stored())
            {
                result.put( f.name(), f.stringValue() );
            }
        }

        return result;
    }

    private Document getOldDocument( IndexingContext context, ArtifactContext ac )
    {
        try
        {
            final IndexSearcher indexSearcher = context.acquireIndexSearcher();
            try
            {
                TopDocs result =
                    indexSearcher.search(
                        new TermQuery( new Term( ArtifactInfo.UINFO, ac.getArtifactInfo().getUinfo() ) ), 2 );

                if ( result.totalHits == 1 )
                {
                    return indexSearcher.doc( result.scoreDocs[0].doc );
                }
            }
            finally
            {
                context.releaseIndexSearcher( indexSearcher );
            }
        }
        catch ( IOException e )
        {
            // huh?
            throw new IllegalStateException( e );
        }
        return null;
    }

    private void updateGroups( IndexingContext context, ArtifactContext ac )
        throws IOException
    {
        String rootGroup = ac.getArtifactInfo().getRootGroup();
        Set<String> rootGroups = context.getRootGroups();
        if ( !rootGroups.contains( rootGroup ) )
        {
            rootGroups.add( rootGroup );
            context.setRootGroups( rootGroups );
        }

        Set<String> allGroups = context.getAllGroups();
        if ( !allGroups.contains( ac.getArtifactInfo().getGroupId() ) )
        {
            allGroups.add( ac.getArtifactInfo().getGroupId() );
            context.setAllGroups( allGroups );
        }
    }
}
