package org.apache.archiva.consumers.core;

/*
 * 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 org.apache.archiva.admin.model.beans.ManagedRepository;
import org.apache.archiva.checksum.ChecksumAlgorithm;
import org.apache.archiva.checksum.ChecksummedFile;
import org.apache.archiva.configuration.ArchivaConfiguration;
import org.apache.archiva.configuration.FileTypes;
import org.apache.archiva.consumers.AbstractMonitoredConsumer;
import org.apache.archiva.consumers.ConsumerException;
import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * ArtifactMissingChecksumsConsumer - Create missing and/or fix invalid checksums for the artifact.
 */
@Service( "knownRepositoryContentConsumer#create-missing-checksums" )
@Scope( "prototype" )
public class ArtifactMissingChecksumsConsumer
    extends AbstractMonitoredConsumer
    implements KnownRepositoryContentConsumer
    // it's prototype bean so we assume configuration won't change during a run
    //, RegistryListener
{

    private Logger log = LoggerFactory.getLogger( ArtifactMissingChecksumsConsumer.class );

    private String id = "create-missing-checksums";

    private String description = "Create Missing and/or Fix Invalid Checksums (.sha1, .md5)";

    private ArchivaConfiguration configuration;

    private FileTypes filetypes;

    private ChecksummedFile checksum;

    private static final String TYPE_CHECKSUM_NOT_FILE = "checksum-bad-not-file";

    private static final String TYPE_CHECKSUM_CANNOT_CALC = "checksum-calc-failure";

    private static final String TYPE_CHECKSUM_CANNOT_CREATE = "checksum-create-failure";

    private File repositoryDir;

    private List<String> includes = new ArrayList<>( 0 );

    @Inject
    public ArtifactMissingChecksumsConsumer( ArchivaConfiguration configuration, FileTypes filetypes )
    {
        this.configuration = configuration;
        this.filetypes = filetypes;

        //configuration.addChangeListener( this );

        initIncludes( );
    }

    @Override
    public String getId( )
    {
        return this.id;
    }

    @Override
    public String getDescription( )
    {
        return this.description;
    }

    @Override
    public void beginScan( ManagedRepository repo, Date whenGathered )
        throws ConsumerException
    {
        this.repositoryDir = new File( repo.getLocation( ) );
    }

    @Override
    public void beginScan( ManagedRepository repo, Date whenGathered, boolean executeOnEntireRepo )
        throws ConsumerException
    {
        beginScan( repo, whenGathered );
    }

    @Override
    public void completeScan( )
    {
        /* do nothing */
    }

    @Override
    public void completeScan( boolean executeOnEntireRepo )
    {
        completeScan( );
    }

    @Override
    public List<String> getExcludes( )
    {
        return getDefaultArtifactExclusions( );
    }

    @Override
    public List<String> getIncludes( )
    {
        return includes;
    }

    @Override
    public void processFile( String path )
        throws ConsumerException
    {
        createFixChecksum( path, ChecksumAlgorithm.SHA1 );
        createFixChecksum( path, ChecksumAlgorithm.MD5 );
    }

    @Override
    public void processFile( String path, boolean executeOnEntireRepo )
        throws ConsumerException
    {
        processFile( path );
    }

    private void createFixChecksum( String path, ChecksumAlgorithm checksumAlgorithm )
    {
        File artifactFile = new File( this.repositoryDir, path );
        File checksumFile = new File( this.repositoryDir, path + "." + checksumAlgorithm.getExt( ) );

        if ( checksumFile.exists( ) )
        {
            checksum = new ChecksummedFile( artifactFile );
            try
            {
                if ( !checksum.isValidChecksum( checksumAlgorithm ) )
                {
                    checksum.fixChecksums( new ChecksumAlgorithm[]{checksumAlgorithm} );
                    log.info( "Fixed checksum file {}", checksumFile.getAbsolutePath( ) );
                    triggerConsumerInfo( "Fixed checksum file " + checksumFile.getAbsolutePath( ) );
                }
            }
            catch ( IOException e )
            {
                log.error( "Cannot calculate checksum for file {} :", checksumFile, e );
                triggerConsumerError( TYPE_CHECKSUM_CANNOT_CALC, "Cannot calculate checksum for file " + checksumFile +
                    ": " + e.getMessage( ) );
            }
        }
        else if ( !checksumFile.exists( ) )
        {
            checksum = new ChecksummedFile( artifactFile );
            try
            {
                checksum.createChecksum( checksumAlgorithm );
                log.info( "Created missing checksum file {}", checksumFile.getAbsolutePath( ) );
                triggerConsumerInfo( "Created missing checksum file " + checksumFile.getAbsolutePath( ) );
            }
            catch ( IOException e )
            {
                log.error( "Cannot create checksum for file {} :", checksumFile, e );
                triggerConsumerError( TYPE_CHECKSUM_CANNOT_CREATE, "Cannot create checksum for file " + checksumFile +
                    ": " + e.getMessage( ) );
            }
        }
        else
        {
            log.warn( "Checksum file {} is not a file. ", checksumFile.getAbsolutePath( ) );
            triggerConsumerWarning( TYPE_CHECKSUM_NOT_FILE,
                "Checksum file " + checksumFile.getAbsolutePath( ) + " is not a file." );
        }
    }

    /*
    @Override
    public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
    {
        if ( ConfigurationNames.isRepositoryScanning( propertyName ) )
        {
            initIncludes();
        }
    }


    @Override
    public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
    {
        // do nothing
    }

    */

    private void initIncludes( )
    {
        includes = new ArrayList<>( filetypes.getFileTypePatterns( FileTypes.ARTIFACTS ) );

    }

    @PostConstruct
    public void initialize( )
    {
        //configuration.addChangeListener( this );

        initIncludes( );
    }
}
