package org.apache.archiva.consumers.core.repository;

/*
 * 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.common.utils.VersionUtil;
import org.apache.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.model.facets.AuditEvent;
import org.apache.archiva.metadata.model.maven2.MavenArtifactFacet;
import org.apache.archiva.metadata.repository.*;
import org.apache.archiva.model.ArtifactReference;
import org.apache.archiva.repository.ContentNotFoundException;
import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.metadata.audit.RepositoryListener;
import org.apache.archiva.repository.storage.StorageAsset;
import org.apache.archiva.repository.storage.StorageUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Base class for all repository purge tasks.
 */
public abstract class AbstractRepositoryPurge
    implements RepositoryPurge
{
    protected Logger log = LoggerFactory.getLogger( getClass( ) );

    protected final ManagedRepositoryContent repository;

    protected final RepositorySession repositorySession;

    protected final List<RepositoryListener> listeners;

    private Logger logger = LoggerFactory.getLogger( "org.apache.archiva.AuditLog" );

    private static final char DELIM = ' ';

    public AbstractRepositoryPurge( ManagedRepositoryContent repository, RepositorySession repositorySession,
                                    List<RepositoryListener> listeners )
    {
        this.repository = repository;
        this.repositorySession = repositorySession;
        this.listeners = listeners;
    }

    /*
     * We have to track namespace, project, project version, artifact version and classifier
     * There is no metadata class that contains all these properties.
     */
    class ArtifactInfo
    {
        final String namespace;
        final String name;
        final String projectVersion;
        String version;
        String classifier;

        ArtifactInfo( String namespace, String name, String projectVersion, String version )
        {
            this.namespace = namespace;
            this.name = name;
            this.projectVersion = projectVersion;
            this.version = version;
        }

        ArtifactInfo( String namespace, String name, String projectVersion )
        {
            this.namespace = namespace;
            this.name = name;
            this.projectVersion = projectVersion;
        }

        /*
         * Creates a info object without version and classifier
         */
        ArtifactInfo projectVersionLevel( )
        {
            return new ArtifactInfo( this.namespace, this.name, this.projectVersion );
        }

        public void setClassifier( String classifier )
        {
            this.classifier = classifier;
        }

        public String getNamespace( )
        {
            return namespace;
        }

        public String getName( )
        {
            return name;
        }

        public String getProjectVersion( )
        {
            return projectVersion;
        }

        public String getVersion( )
        {
            return version;
        }

        public String getClassifier( )
        {
            return classifier;
        }

        public boolean hasClassifier( )
        {
            return classifier != null && !"".equals( classifier );
        }

        @Override
        public boolean equals( Object o )
        {
            if ( this == o ) return true;
            if ( o == null || getClass( ) != o.getClass( ) ) return false;

            ArtifactInfo that = (ArtifactInfo) o;

            if ( !namespace.equals( that.namespace ) ) return false;
            if ( !name.equals( that.name ) ) return false;
            if ( !projectVersion.equals( that.projectVersion ) ) return false;
            if ( !( version != null ? version.equals( that.version ) : that.version == null ) ) return false;
            return classifier != null ? classifier.equals( that.classifier ) : that.classifier == null;
        }

        @Override
        public int hashCode( )
        {
            int result = namespace.hashCode( );
            result = 31 * result + name.hashCode( );
            result = 31 * result + projectVersion.hashCode( );
            result = 31 * result + ( version != null ? version.hashCode( ) : 0 );
            result = 31 * result + ( classifier != null ? classifier.hashCode( ) : 0 );
            return result;
        }

        @Override
        public String toString( )
        {
            final StringBuilder sb = new StringBuilder( "ArtifactInfo{" );
            sb.append( "namespace='" ).append( namespace ).append( '\'' );
            sb.append( ", name='" ).append( name ).append( '\'' );
            sb.append( ", projectVersion='" ).append( projectVersion ).append( '\'' );
            sb.append( ", version='" ).append( version ).append( '\'' );
            sb.append( ", classifier='" ).append( classifier ).append( '\'' );
            sb.append( '}' );
            return sb.toString( );
        }
    }

    /**
     * Purge the repo. Update db and index of removed artifacts.
     *
     * @param references
     */
    protected void purge( Set<ArtifactReference> references )
    {
        if ( references != null && !references.isEmpty( ) )
        {
            MetadataRepository metadataRepository = repositorySession.getRepository( );
            Map<ArtifactInfo, ArtifactMetadata> metaRemovalList = new HashMap<>( );
            Map<String, Collection<ArtifactMetadata>> metaResolved = new HashMap<>( );
            for ( ArtifactReference reference : references )
            {
                String baseVersion = VersionUtil.getBaseVersion( reference.getVersion( ) );
                // Needed for tracking in the hashmap
                String metaBaseId = reference.getGroupId( ) + "/" + reference.getArtifactId( ) + "/" + baseVersion;

                if ( !metaResolved.containsKey( metaBaseId ) )
                {
                    try
                    {
                        metaResolved.put( metaBaseId, metadataRepository.getArtifacts(repositorySession, repository.getId( ),
                            reference.getGroupId( ), reference.getArtifactId( ), baseVersion ) );
                    }
                    catch ( MetadataResolutionException e )
                    {
                        log.error( "Error during metadata retrieval {}: {}", metaBaseId, e.getMessage( ) );
                    }
                }
                StorageAsset artifactFile = repository.toFile( reference );

                for ( RepositoryListener listener : listeners )
                {
                    listener.deleteArtifact( metadataRepository, repository.getId( ), reference.getGroupId( ),
                        reference.getArtifactId( ), reference.getVersion( ),
                            artifactFile.getName( ));
                }
                try
                {
                    artifactFile.getStorage().removeAsset(artifactFile);
                    log.debug( "File deleted: {}", artifactFile );
                }
                catch ( IOException e )
                {
                    log.error( "Could not delete file {}: {}", artifactFile.toString(), e.getMessage( ), e );
                    continue;
                }
                try
                {
                    repository.deleteArtifact( reference );
                }
                catch ( ContentNotFoundException e )
                {
                    log.warn( "skip error deleting artifact {}: {}", reference, e.getMessage( ) );
                }
                catch ( org.apache.archiva.repository.ContentAccessException e )
                {
                    e.printStackTrace( );
                }

                boolean snapshotVersion = VersionUtil.isSnapshot( reference.getVersion( ) );


                // If this is a snapshot we have to search for artifacts with the same version. And remove all of them.
                if ( snapshotVersion )
                {
                    Collection<ArtifactMetadata> artifacts =
                        metaResolved.get( metaBaseId );
                    if ( artifacts != null )
                    {
                        // cleanup snapshots metadata
                        for ( ArtifactMetadata artifactMetadata : artifacts )
                        {
                            // Artifact metadata and reference version should match.
                            if ( artifactMetadata.getVersion( ).equals( reference.getVersion( ) ) )
                            {
                                ArtifactInfo info = new ArtifactInfo( artifactMetadata.getNamespace( ), artifactMetadata.getProject( ), artifactMetadata.getProjectVersion( ), artifactMetadata.getVersion( ) );
                                if ( StringUtils.isNotBlank( reference.getClassifier( ) ) )
                                {
                                    info.setClassifier( reference.getClassifier( ) );
                                    metaRemovalList.put( info, artifactMetadata );
                                }
                                else
                                {
                                    // metadataRepository.removeTimestampedArtifact( artifactMetadata, baseVersion );
                                    metaRemovalList.put( info, artifactMetadata );
                                }
                            }
                        }
                    }
                }
                else // otherwise we delete the artifact version
                {
                    ArtifactInfo info = new ArtifactInfo( reference.getGroupId( ), reference.getArtifactId( ), baseVersion, reference.getVersion( ) );
                    for ( ArtifactMetadata metadata : metaResolved.get( metaBaseId ) )
                    {
                        metaRemovalList.put( info, metadata );
                    }
                }
                triggerAuditEvent( repository.getRepository( ).getId( ), ArtifactReference.toKey( reference ),
                    AuditEvent.PURGE_ARTIFACT );
                purgeSupportFiles( artifactFile );
            }
            purgeMetadata( metadataRepository, metaRemovalList );
            try
            {
                repositorySession.save( );
            }
            catch ( org.apache.archiva.metadata.repository.MetadataSessionException e )
            {
                e.printStackTrace( );
            }

        }
    }

    /*
     * Purges the metadata. First removes the artifacts. After that empty versions will be removed.
     */
    private void purgeMetadata( MetadataRepository metadataRepository, Map<ArtifactInfo, ArtifactMetadata> dataList )
    {
        Set<ArtifactInfo> projectLevelMetadata = new HashSet<>( );
        for ( Map.Entry<ArtifactInfo, ArtifactMetadata> infoEntry : dataList.entrySet( ) )
        {
            ArtifactInfo info = infoEntry.getKey( );
            try
            {
                removeArtifact( metadataRepository, info, infoEntry.getValue( ) );
                log.debug( "Removed artifact from MetadataRepository {}", info );
            }
            catch ( MetadataRepositoryException e )
            {
                log.error( "Could not remove artifact from MetadataRepository {}: {}", info, e.getMessage( ), e );
            }
            projectLevelMetadata.add( info.projectVersionLevel( ) );
        }
        try {
            repositorySession.save( );
        } catch (MetadataSessionException e) {
            log.error("Could not save sesion {}", e.getMessage());
        }
        Collection<ArtifactMetadata> artifacts = null;
        // Get remaining artifacts and remove project if empty
        for ( ArtifactInfo info : projectLevelMetadata )
        {
            try
            {
                artifacts = metadataRepository.getArtifacts(repositorySession , repository.getId( ), info.getNamespace( ),
                    info.getName( ), info.getProjectVersion( ) );
                if ( artifacts.size( ) == 0 )
                {
                    metadataRepository.removeProjectVersion(repositorySession , repository.getId( ),
                        info.getNamespace( ), info.getName( ), info.getProjectVersion( ) );
                    log.debug( "Removed project version from MetadataRepository {}", info );
                }
            }
            catch ( MetadataResolutionException | MetadataRepositoryException e )
            {
                log.error( "Could not remove project version from MetadataRepository {}: {}", info, e.getMessage( ), e );
            }
        }
        try {
            repositorySession.save( );
        } catch (MetadataSessionException e) {
            log.error("Could not save sesion {}", e.getMessage());

        }

    }

    /*
     * Removes the artifact from the metadataRepository. If a classifier is set, the facet will be removed.
     */
    private void removeArtifact( MetadataRepository metadataRepository, ArtifactInfo artifactInfo, ArtifactMetadata artifactMetadata ) throws MetadataRepositoryException
    {
        if ( artifactInfo.hasClassifier( ) )
        {
            // cleanup facet which contains classifier information
            MavenArtifactFacet mavenArtifactFacet =
                (MavenArtifactFacet) artifactMetadata.getFacet(
                    MavenArtifactFacet.FACET_ID );

            if ( StringUtils.equals( artifactInfo.classifier,
                mavenArtifactFacet.getClassifier( ) ) )
            {
                artifactMetadata.removeFacet( MavenArtifactFacet.FACET_ID );
                String groupId = artifactInfo.getNamespace( ), artifactId =
                    artifactInfo.getName( ),
                    version = artifactInfo.getProjectVersion( );
                MavenArtifactFacet mavenArtifactFacetToCompare = new MavenArtifactFacet( );
                mavenArtifactFacetToCompare.setClassifier( artifactInfo.getClassifier( ) );
                metadataRepository.removeFacetFromArtifact(repositorySession , repository.getId( ), groupId,
                    artifactId, version, mavenArtifactFacetToCompare );
                try {
                    repositorySession.save( );
                } catch (MetadataSessionException e) {
                    log.error("Could not save session {}", e.getMessage());
                }
            }
        }
        else
        {
            metadataRepository.removeTimestampedArtifact(repositorySession , artifactMetadata, artifactInfo.getProjectVersion( ) );
        }
    }

    private void deleteSilently( StorageAsset path )
    {
        try
        {
            path.getStorage().removeAsset(path);
            triggerAuditEvent( repository.getRepository( ).getId( ), path.toString( ), AuditEvent.PURGE_FILE );
        }
        catch ( IOException e )
        {
            log.error( "Error occured during file deletion {}: {} ", path, e.getMessage( ), e );
        }
    }

    /**
     * <p>
     * This find support files for the artifactFile and deletes them.
     * </p>
     * <p>
     * Support Files are things like ".sha1", ".md5", ".asc", etc.
     * </p>
     *
     * @param artifactFile the file to base off of.
     */
    private void purgeSupportFiles( StorageAsset artifactFile )
    {
        StorageAsset parentDir = artifactFile.getParent( );

        if ( !parentDir.exists() )
        {
            return;
        }

        final String artifactName = artifactFile.getName( );

        try
        {

            StorageUtil.recurse(parentDir, a -> {
                if (!a.isContainer() && a.getName().startsWith(artifactName)) deleteSilently(a);
            }, true, 3 );
        }
        catch ( IOException e )
        {
            log.error( "Purge of support files failed {}: {}", artifactFile, e.getMessage( ), e );
        }

    }

    private void triggerAuditEvent( String repoId, String resource, String action )
    {
        String msg =
            repoId + DELIM + "<system-purge>" + DELIM + "<system>" + DELIM + '\"' + resource + '\"' + DELIM + '\"' +
                action + '\"';

        logger.info( msg );
    }
}
