package org.apache.maven.index.packer;

/*
 * 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.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.TimeZone;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.apache.maven.index.context.IndexingContext;
import org.apache.maven.index.incremental.IncrementalHandler;
import org.apache.maven.index.updater.IndexDataWriter;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A default {@link IndexPacker} implementation. Creates the properties, legacy index zip and new gz files.
 *
 * @author Tamas Cservenak
 * @author Eugene Kuleshov
 */
@Singleton
@Named
public class DefaultIndexPacker
    implements IndexPacker
{

    private final Logger logger = LoggerFactory.getLogger( getClass() );

    protected Logger getLogger()
    {
        return logger;
    }

    private final IncrementalHandler incrementalHandler;


    @Inject
    public DefaultIndexPacker( IncrementalHandler incrementalHandler )
    {
        this.incrementalHandler = incrementalHandler;
    }

    public void packIndex( IndexPackingRequest request )
        throws IOException, IllegalArgumentException
    {
        if ( request.getTargetDir() == null )
        {
            throw new IllegalArgumentException( "The target dir is null" );
        }

        if ( request.getTargetDir().exists() )
        {
            if ( !request.getTargetDir().isDirectory() )
            {
                throw new IllegalArgumentException( //
                                                    String.format( "Specified target path %s is not a directory",
                                                                   request.getTargetDir().getAbsolutePath() ) );
            }
            if ( !request.getTargetDir().canWrite() )
            {
                throw new IllegalArgumentException( String.format( "Specified target path %s is not writtable",
                                                                   request.getTargetDir().getAbsolutePath() ) );
            }
        }
        else
        {
            if ( !request.getTargetDir().mkdirs() )
            {
                throw new IllegalArgumentException( "Can't create " + request.getTargetDir().getAbsolutePath() );
            }
        }

        // These are all of the files we'll be dealing with (except for the incremental chunks of course)
        File v1File = new File( request.getTargetDir(), IndexingContext.INDEX_FILE_PREFIX + ".gz" );

        Properties info = null;

        try
        {
            // Note that for incremental indexes to work properly, a valid index.properties file
            // must be present
            info = readIndexProperties( request );

            if ( request.isCreateIncrementalChunks() )
            {
                List<Integer> chunk = incrementalHandler.getIncrementalUpdates( request, info );

                if ( chunk == null )
                {
                    getLogger().debug( "Problem with Chunks, forcing regeneration of whole index" );
                    incrementalHandler.initializeProperties( info );
                }
                else if ( chunk.isEmpty() )
                {
                    getLogger().debug( "No incremental changes, not writing new incremental chunk" );
                }
                else
                {
                    File file = new File( request.getTargetDir(), //
                                          IndexingContext.INDEX_FILE_PREFIX + "." + info.getProperty(
                                              IndexingContext.INDEX_CHUNK_COUNTER ) + ".gz" );

                    writeIndexData( request, chunk, file );

                    if ( request.isCreateChecksumFiles() )
                    {
                        FileUtils.fileWrite(
                            new File( file.getParentFile(), file.getName() + ".sha1" ).getAbsolutePath(),
                            DigesterUtils.getSha1Digest( file ) );

                        FileUtils.fileWrite(
                            new File( file.getParentFile(), file.getName() + ".md5" ).getAbsolutePath(),
                            DigesterUtils.getMd5Digest( file ) );
                    }
                }
            }
        }
        catch ( IOException e )
        {
            getLogger().info( "Unable to read properties file, will force index regeneration" );
            info = new Properties();
            incrementalHandler.initializeProperties( info );
        }

        Date timestamp = request.getContext().getTimestamp();

        if ( timestamp == null )
        {
            timestamp = new Date( 0 ); // never updated
        }

        if ( request.getFormats().contains( IndexPackingRequest.IndexFormat.FORMAT_V1 ) )
        {
            info.setProperty( IndexingContext.INDEX_TIMESTAMP, format( timestamp ) );

            writeIndexData( request, null, v1File );

            if ( request.isCreateChecksumFiles() )
            {
                FileUtils.fileWrite( new File( v1File.getParentFile(), v1File.getName() + ".sha1" ).getAbsolutePath(),
                                     DigesterUtils.getSha1Digest( v1File ) );

                FileUtils.fileWrite( new File( v1File.getParentFile(), v1File.getName() + ".md5" ).getAbsolutePath(),
                                     DigesterUtils.getMd5Digest( v1File ) );
            }
        }

        writeIndexProperties( request, info );
    }

    private Properties readIndexProperties( IndexPackingRequest request )
        throws IOException
    {
        File file = null;

        if ( request.isUseTargetProperties() || request.getContext().getIndexDirectoryFile() == null )
        {
            file = new File( request.getTargetDir(), IndexingContext.INDEX_REMOTE_PROPERTIES_FILE );
        }
        else
        {
            file =
                new File( request.getContext().getIndexDirectoryFile(), IndexingContext.INDEX_PACKER_PROPERTIES_FILE );
        }

        Properties properties = new Properties();

        FileInputStream fos = null;

        try
        {
            fos = new FileInputStream( file );
            properties.load( fos );
        }
        finally
        {
            if ( fos != null )
            {
                fos.close();
            }
        }

        return properties;
    }

    void writeIndexData( IndexPackingRequest request, List<Integer> docIndexes, File targetArchive )
        throws IOException
    {
        if ( targetArchive.exists() )
        {
            targetArchive.delete();
        }

        try( OutputStream os = new FileOutputStream( targetArchive ) )
        {
            IndexDataWriter dw = new IndexDataWriter( os );
            dw.write( request.getContext(), request.getIndexReader(), docIndexes );

            os.flush();
        }
    }

    void writeIndexProperties( IndexPackingRequest request, Properties info )
        throws IOException
    {
        File propertyFile =
            new File( request.getContext().getIndexDirectoryFile(), IndexingContext.INDEX_PACKER_PROPERTIES_FILE );
        File targetPropertyFile = new File( request.getTargetDir(), IndexingContext.INDEX_REMOTE_PROPERTIES_FILE );

        info.setProperty( IndexingContext.INDEX_ID, request.getContext().getId() );

        try (OutputStream os = new FileOutputStream( propertyFile ))
        {
            info.store( os, null );
        }

        try (OutputStream os = new FileOutputStream( targetPropertyFile ))
        {
            info.store( os, null );
        }

        if ( request.isCreateChecksumFiles() )
        {
            FileUtils.fileWrite( new File( targetPropertyFile.getParentFile(),
                                           targetPropertyFile.getName() + ".sha1" ).getAbsolutePath(),
                                 DigesterUtils.getSha1Digest( targetPropertyFile ) );

            FileUtils.fileWrite(
                new File( targetPropertyFile.getParentFile(), targetPropertyFile.getName() + ".md5" ).getAbsolutePath(),
                DigesterUtils.getMd5Digest( targetPropertyFile ) );
        }
    }

    private String format( Date d )
    {
        SimpleDateFormat df = new SimpleDateFormat( IndexingContext.INDEX_TIME_FORMAT );
        df.setTimeZone( TimeZone.getTimeZone( "GMT" ) );
        return df.format( d );
    }
}
