package org.apache.archiva.rest.services;

/*
 * 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.RepositoryAdminException;
import org.apache.archiva.admin.model.admin.ArchivaAdministration;
import org.apache.archiva.checksum.ChecksumAlgorithm;
import org.apache.archiva.checksum.ChecksummedFile;
import org.apache.archiva.common.utils.VersionComparator;
import org.apache.archiva.common.utils.VersionUtil;
import org.apache.archiva.maven2.model.Artifact;
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.ArchivaRepositoryMetadata;
import org.apache.archiva.model.ArtifactReference;
import org.apache.archiva.model.VersionedReference;
import org.apache.archiva.redback.authentication.AuthenticationResult;
import org.apache.archiva.redback.authorization.AuthorizationException;
import org.apache.archiva.components.cache.Cache;
import org.apache.archiva.components.taskqueue.TaskQueueException;
import org.apache.archiva.redback.system.DefaultSecuritySession;
import org.apache.archiva.redback.system.SecuritySession;
import org.apache.archiva.redback.system.SecuritySystem;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserManagerException;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.apache.archiva.repository.ContentNotFoundException;
import org.apache.archiva.repository.LayoutException;
import org.apache.archiva.repository.ManagedRepository;
import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.RepositoryException;
import org.apache.archiva.repository.RepositoryNotFoundException;
import org.apache.archiva.repository.RepositoryRegistry;
import org.apache.archiva.repository.RepositoryType;
import org.apache.archiva.repository.storage.RepositoryStorage;
import org.apache.archiva.repository.storage.StorageAsset;
import org.apache.archiva.repository.storage.StorageUtil;
import org.apache.archiva.metadata.audit.RepositoryListener;
import org.apache.archiva.repository.metadata.base.MetadataTools;
import org.apache.archiva.repository.metadata.RepositoryMetadataException;
import org.apache.archiva.repository.metadata.base.RepositoryMetadataWriter;
import org.apache.archiva.repository.scanner.RepositoryScanStatistics;
import org.apache.archiva.repository.scanner.RepositoryScanner;
import org.apache.archiva.repository.scanner.RepositoryScannerException;
import org.apache.archiva.repository.scanner.RepositoryScannerInstance;
import org.apache.archiva.rest.api.model.ArtifactTransferRequest;
import org.apache.archiva.rest.api.model.StringList;
import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
import org.apache.archiva.rest.api.services.RepositoriesService;
import org.apache.archiva.scheduler.ArchivaTaskScheduler;
import org.apache.archiva.scheduler.indexing.maven.ArchivaIndexingTaskExecutor;
import org.apache.archiva.scheduler.indexing.ArtifactIndexingTask;
import org.apache.archiva.scheduler.indexing.DownloadRemoteIndexException;
import org.apache.archiva.scheduler.indexing.DownloadRemoteIndexScheduler;
import org.apache.archiva.scheduler.repository.model.RepositoryTask;
import org.apache.archiva.security.ArchivaSecurityException;
import org.apache.archiva.security.common.ArchivaRoleConstants;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.inject.Inject;
import javax.inject.Named;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.file.Path;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

/**
 * @author Olivier Lamy
 * @since 1.4-M1
 */
@Service("repositoriesService#rest")
public class DefaultRepositoriesService
    extends AbstractRestService
    implements RepositoriesService
{
    private Logger log = LoggerFactory.getLogger( getClass() );

    @Inject
    @Named(value = "taskExecutor#indexing")
    private ArchivaIndexingTaskExecutor archivaIndexingTaskExecutor;

    @Inject
    private RepositoryRegistry repositoryRegistry;

    @Inject
    private SecuritySystem securitySystem;

    @Inject
    @Named(value = "archivaTaskScheduler#repository")
    private ArchivaTaskScheduler<RepositoryTask> scheduler;

    @Inject
    private DownloadRemoteIndexScheduler downloadRemoteIndexScheduler;

    @Inject
    @Named(value = "repositorySessionFactory")
    protected RepositorySessionFactory repositorySessionFactory;

    @Inject
    @Autowired(required = false)
    protected List<RepositoryListener> listeners = new ArrayList<RepositoryListener>();

    @Inject
    private RepositoryScanner repoScanner;

    /**
     * Cache used for namespaces
     */
    @Inject
    @Named(value = "cache#namespaces")
    private Cache<String, Collection<String>> namespacesCache;

    private List<ChecksumAlgorithm> algorithms = Arrays.asList(ChecksumAlgorithm.SHA256, ChecksumAlgorithm.SHA1, ChecksumAlgorithm.MD5 );

    @Override
    public Boolean scanRepository( String repositoryId, boolean fullScan )
    {
        return doScanRepository( repositoryId, fullScan );
    }

    @Override
    public Boolean alreadyScanning( String repositoryId )
    {
        // check queue first to make sure it doesn't get dequeued between calls
        if ( repositoryTaskScheduler.isProcessingRepositoryTask( repositoryId ) )
        {
            return true;
        }
        for ( RepositoryScannerInstance scan : repoScanner.getInProgressScans() )
        {
            if ( scan.getRepository().getId().equals( repositoryId ) )
            {
                return true;
            }
        }
        return false;
    }

    @Override
    public Boolean removeScanningTaskFromQueue( String repositoryId )
    {
        RepositoryTask task = new RepositoryTask();
        task.setRepositoryId( repositoryId );
        try
        {
            return repositoryTaskScheduler.unQueueTask( task );
        }
        catch ( TaskQueueException e )
        {
            log.error( "failed to unschedule scanning of repo with id {}", repositoryId, e );
            return false;
        }
    }

    private ManagedRepositoryContent getManagedRepositoryContent(String id) throws RepositoryException
    {
        org.apache.archiva.repository.ManagedRepository repo = repositoryRegistry.getManagedRepository( id );
        if (repo==null) {
            throw new RepositoryException( "Repository not found "+id );
        }
        return repo.getContent();
    }

    @Override
    public Boolean scanRepositoryNow( String repositoryId, boolean fullScan )
        throws ArchivaRestServiceException
    {

        try
        {

            org.apache.archiva.repository.ManagedRepository repository = repositoryRegistry.getManagedRepository( repositoryId );


            ArtifactIndexingTask task =
                new ArtifactIndexingTask( repository, null, ArtifactIndexingTask.Action.FINISH, repository.getIndexingContext() );

            task.setExecuteOnEntireRepo( true );
            task.setOnlyUpdate( !fullScan );

            archivaIndexingTaskExecutor.executeTask( task );

            scheduler.queueTask( new RepositoryTask( repositoryId, fullScan ) );

            return Boolean.TRUE;
        }
        catch ( Exception e )
        {
            log.error( e.getMessage(), e );
            throw new ArchivaRestServiceException( e.getMessage(), e );
        }
    }

    @Override
    public Boolean scheduleDownloadRemoteIndex( String repositoryId, boolean now, boolean fullDownload )
        throws ArchivaRestServiceException
    {
        try
        {
            downloadRemoteIndexScheduler.scheduleDownloadRemote( repositoryId, now, fullDownload );
        }
        catch ( DownloadRemoteIndexException e )
        {
            log.error( e.getMessage(), e );
            throw new ArchivaRestServiceException( e.getMessage(), e );
        }
        return Boolean.TRUE;
    }

    @Override
    public Boolean copyArtifact( ArtifactTransferRequest artifactTransferRequest )
        throws ArchivaRestServiceException
    {
        // check parameters
        String userName = getAuditInformation().getUser().getUsername();
        if ( StringUtils.isBlank( userName ) )
        {
            throw new ArchivaRestServiceException( "copyArtifact call: userName not found", null );
        }

        if ( StringUtils.isBlank( artifactTransferRequest.getRepositoryId() ) )
        {
            throw new ArchivaRestServiceException( "copyArtifact call: sourceRepositoryId cannot be null", null );
        }

        if ( StringUtils.isBlank( artifactTransferRequest.getTargetRepositoryId() ) )
        {
            throw new ArchivaRestServiceException( "copyArtifact call: targetRepositoryId cannot be null", null );
        }

        ManagedRepository source = null;
        source = repositoryRegistry.getManagedRepository( artifactTransferRequest.getRepositoryId() );

        if ( source == null )
        {
            throw new ArchivaRestServiceException(
                "cannot find repository with id " + artifactTransferRequest.getRepositoryId(), null );
        }

        ManagedRepository target = null;
        target = repositoryRegistry.getManagedRepository( artifactTransferRequest.getTargetRepositoryId() );

        if ( target == null )
        {
            throw new ArchivaRestServiceException(
                "cannot find repository with id " + artifactTransferRequest.getTargetRepositoryId(), null );
        }

        if ( StringUtils.isBlank( artifactTransferRequest.getGroupId() ) )
        {
            throw new ArchivaRestServiceException( "groupId is mandatory", null );
        }

        if ( StringUtils.isBlank( artifactTransferRequest.getArtifactId() ) )
        {
            throw new ArchivaRestServiceException( "artifactId is mandatory", null );
        }

        if ( StringUtils.isBlank( artifactTransferRequest.getVersion() ) )
        {
            throw new ArchivaRestServiceException( "version is mandatory", null );
        }

        if ( VersionUtil.isSnapshot( artifactTransferRequest.getVersion() ) )
        {
            throw new ArchivaRestServiceException( "copy of SNAPSHOT not supported", null );
        }

        // end check parameters

        User user = null;
        try
        {
            user = securitySystem.getUserManager().findUser( userName );
        }
        catch ( UserNotFoundException e )
        {
            throw new ArchivaRestServiceException( "user " + userName + " not found", e );
        }
        catch ( UserManagerException e )
        {
            throw new ArchivaRestServiceException( "ArchivaRestServiceException:" + e.getMessage(), e );
        }

        // check karma on source : read
        AuthenticationResult authn = new AuthenticationResult( true, userName, null );
        SecuritySession securitySession = new DefaultSecuritySession( authn, user );
        try
        {
            boolean authz =
                securitySystem.isAuthorized( securitySession, ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS,
                                             artifactTransferRequest.getRepositoryId() );
            if ( !authz )
            {
                throw new ArchivaRestServiceException(
                    "not authorized to access repo:" + artifactTransferRequest.getRepositoryId(), null );
            }
        }
        catch ( AuthorizationException e )
        {
            log.error( "error reading permission: {}", e.getMessage(), e );
            throw new ArchivaRestServiceException( e.getMessage(), e );
        }

        // check karma on target: write
        try
        {
            boolean authz =
                securitySystem.isAuthorized( securitySession, ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD,
                                             artifactTransferRequest.getTargetRepositoryId() );
            if ( !authz )
            {
                throw new ArchivaRestServiceException(
                    "not authorized to write to repo:" + artifactTransferRequest.getTargetRepositoryId(), null );
            }
        }
        catch ( AuthorizationException e )
        {
            log.error( "error reading permission: {}", e.getMessage(), e );
            throw new ArchivaRestServiceException( e.getMessage(), e );
        }

        // sounds good we can continue !

        ArtifactReference artifactReference = new ArtifactReference();
        artifactReference.setArtifactId( artifactTransferRequest.getArtifactId() );
        artifactReference.setGroupId( artifactTransferRequest.getGroupId() );
        artifactReference.setVersion( artifactTransferRequest.getVersion() );
        artifactReference.setClassifier( artifactTransferRequest.getClassifier() );
        String packaging = StringUtils.trim( artifactTransferRequest.getPackaging() );
        artifactReference.setType( StringUtils.isEmpty( packaging ) ? "jar" : packaging );

        try
        {

            ManagedRepositoryContent sourceRepository =
                getManagedRepositoryContent( artifactTransferRequest.getRepositoryId() );

            String artifactSourcePath = sourceRepository.toPath( artifactReference );

            if ( StringUtils.isEmpty( artifactSourcePath ) )
            {
                log.error( "cannot find artifact {}", artifactTransferRequest );
                throw new ArchivaRestServiceException( "cannot find artifact " + artifactTransferRequest.toString(),
                                                       null );
            }

            StorageAsset artifactFile = source.getAsset( artifactSourcePath );

            if ( !artifactFile.exists() )
            {
                log.error( "cannot find artifact {}", artifactTransferRequest );
                throw new ArchivaRestServiceException( "cannot find artifact " + artifactTransferRequest.toString(),
                                                       null );
            }

            ManagedRepositoryContent targetRepository =
                getManagedRepositoryContent( artifactTransferRequest.getTargetRepositoryId() );

            String artifactPath = targetRepository.toPath( artifactReference );

            int lastIndex = artifactPath.lastIndexOf( '/' );

            String path = artifactPath.substring( 0, lastIndex );
            StorageAsset targetDir = target.getAsset( path );

            Date lastUpdatedTimestamp = Calendar.getInstance().getTime();
            int newBuildNumber = 1;
            String timestamp = null;

            StorageAsset versionMetadataFile = target.getAsset(path + "/" + MetadataTools.MAVEN_METADATA );
            /* unused */ getMetadata( targetRepository.getRepository().getType(), versionMetadataFile );

            if ( !targetDir.exists() )
            {
                targetDir = target.addAsset(targetDir.getPath(), true);
                targetDir.create();
            }

            String filename = artifactPath.substring( lastIndex + 1 );

            boolean fixChecksums =
                !( archivaAdministration.getKnownContentConsumers().contains( "create-missing-checksums" ) );

            StorageAsset targetFile = target.getAsset(targetDir.getPath() + "/" + filename );
            if ( targetFile.exists() && target.blocksRedeployments())
            {
                throw new ArchivaRestServiceException(
                    "artifact already exists in target repo: " + artifactTransferRequest.getTargetRepositoryId()
                        + " and redeployment blocked", null
                );
            }
            else
            {
                copyFile(artifactFile, targetFile, fixChecksums );
                queueRepositoryTask( target.getId(), targetFile );
            }

            // copy source pom to target repo
            String pomFilename = filename;
            if ( StringUtils.isNotBlank( artifactTransferRequest.getClassifier() ) )
            {
                pomFilename = StringUtils.remove( pomFilename, "-" + artifactTransferRequest.getClassifier() );
            }
            pomFilename = FilenameUtils.removeExtension( pomFilename ) + ".pom";

            StorageAsset pomFile = source.getAsset(
                artifactSourcePath.substring( 0, artifactPath.lastIndexOf( '/' ) )+"/"+ pomFilename );

            if ( pomFile != null && pomFile.exists() )
            {
                StorageAsset targetPomFile = target.getAsset( targetDir.getPath() + "/" + pomFilename );
                copyFile(pomFile, targetPomFile, fixChecksums );
                queueRepositoryTask( target.getId(), targetPomFile );


            }

            // explicitly update only if metadata-updater consumer is not enabled!
            if ( !archivaAdministration.getKnownContentConsumers().contains( "metadata-updater" ) )
            {
                updateProjectMetadata( target.getType(), target, targetDir, lastUpdatedTimestamp, timestamp, newBuildNumber,
                                       fixChecksums, artifactTransferRequest );


            }

            String msg =
                "Artifact \'" + artifactTransferRequest.getGroupId() + ":" + artifactTransferRequest.getArtifactId()
                    + ":" + artifactTransferRequest.getVersion() + "\' was successfully deployed to repository \'"
                    + artifactTransferRequest.getTargetRepositoryId() + "\'";
            log.debug("copyArtifact {}", msg);

        }
        catch ( RepositoryException e )
        {
            log.error( "RepositoryException: {}", e.getMessage(), e );
            throw new ArchivaRestServiceException( e.getMessage(), e );
        }
        catch ( RepositoryAdminException e )
        {
            log.error( "RepositoryAdminException: {}", e.getMessage(), e );
            throw new ArchivaRestServiceException( e.getMessage(), e );
        }
        catch ( IOException e )
        {
            log.error( "IOException: {}", e.getMessage(), e );
            throw new ArchivaRestServiceException( e.getMessage(), e );
        }
        return true;
    }

    private void queueRepositoryTask( String repositoryId, StorageAsset localFile )
    {

        RepositoryTask task = new RepositoryTask();
        task.setRepositoryId( repositoryId );
        task.setResourceFile( localFile );
        task.setUpdateRelatedArtifacts( true );
        //task.setScanAll( true );

        try
        {
            scheduler.queueTask( task );
        }
        catch ( TaskQueueException e )
        {
            log.error( "Unable to queue repository task to execute consumers on resource file ['{}"
                           + "'].", localFile.getName());
        }
    }

    private ArchivaRepositoryMetadata getMetadata( RepositoryType repositoryType, StorageAsset metadataFile )
        throws RepositoryMetadataException
    {
        ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
        if ( metadataFile.exists() )
        {
            metadata = repositoryRegistry.getMetadataReader( repositoryType ).read( metadataFile );
        }
        return metadata;
    }

    private StorageAsset getMetadata( RepositoryStorage storage, String targetPath )
    {
        return storage.getAsset( targetPath + "/" + MetadataTools.MAVEN_METADATA );

    }

    /*
     * Copies the asset to the new target.
     */
    private void copyFile(StorageAsset sourceFile, StorageAsset targetPath, boolean fixChecksums)
        throws IOException
    {

        StorageUtil.copyAsset( sourceFile, targetPath, true );
        if ( fixChecksums )
        {
            fixChecksums( targetPath );
        }
    }

    private void fixChecksums( StorageAsset file )
    {
        Path destinationFile = file.getFilePath();
        if (destinationFile!=null)
        {
            ChecksummedFile checksum = new ChecksummedFile( destinationFile );
            checksum.fixChecksums( algorithms );
        }
    }

    private void updateProjectMetadata( RepositoryType repositoryType, RepositoryStorage storage, StorageAsset targetPath, Date lastUpdatedTimestamp, String timestamp, int buildNumber,
                                        boolean fixChecksums, ArtifactTransferRequest artifactTransferRequest )
        throws RepositoryMetadataException
    {
        List<String> availableVersions = new ArrayList<>();
        String latestVersion = artifactTransferRequest.getVersion();

        StorageAsset projectDir = targetPath.getParent();
        StorageAsset projectMetadataFile = storage.getAsset( projectDir.getPath()+"/"+MetadataTools.MAVEN_METADATA );

        ArchivaRepositoryMetadata projectMetadata = getMetadata( repositoryType, projectMetadataFile );

        if ( projectMetadataFile.exists() )
        {
            availableVersions = projectMetadata.getAvailableVersions();

            Collections.sort( availableVersions, VersionComparator.getInstance() );

            if ( !availableVersions.contains( artifactTransferRequest.getVersion() ) )
            {
                availableVersions.add( artifactTransferRequest.getVersion() );
            }

            latestVersion = availableVersions.get( availableVersions.size() - 1 );
        }
        else
        {
            availableVersions.add( artifactTransferRequest.getVersion() );

            projectMetadata.setGroupId( artifactTransferRequest.getGroupId() );
            projectMetadata.setArtifactId( artifactTransferRequest.getArtifactId() );
        }

        if ( projectMetadata.getGroupId() == null )
        {
            projectMetadata.setGroupId( artifactTransferRequest.getGroupId() );
        }

        if ( projectMetadata.getArtifactId() == null )
        {
            projectMetadata.setArtifactId( artifactTransferRequest.getArtifactId() );
        }

        projectMetadata.setLatestVersion( latestVersion );
        projectMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
        projectMetadata.setAvailableVersions( availableVersions );

        if ( !VersionUtil.isSnapshot( artifactTransferRequest.getVersion() ) )
        {
            projectMetadata.setReleasedVersion( latestVersion );
        }

        try(OutputStreamWriter writer = new OutputStreamWriter(projectMetadataFile.getWriteStream(true))) {
            RepositoryMetadataWriter.write(projectMetadata, writer);
        } catch (IOException e) {
            throw new RepositoryMetadataException(e);
        }

        if ( fixChecksums )
        {
            fixChecksums( projectMetadataFile );
        }
    }

    @Override
    public Boolean removeProjectVersion( String repositoryId, String namespace, String projectId, String version )
        throws ArchivaRestServiceException
    {
        // if not a generic we can use the standard way to delete artifact
        if ( !VersionUtil.isGenericSnapshot( version ) )
        {
            Artifact artifact = new Artifact( namespace, projectId, version );
            artifact.setRepositoryId( repositoryId );
            artifact.setContext( repositoryId );
            return deleteArtifact( artifact );
        }

        if ( StringUtils.isEmpty( repositoryId ) )
        {
            throw new ArchivaRestServiceException( "repositoryId cannot be null", 400, null );
        }

        if ( !isAuthorizedToDeleteArtifacts( repositoryId ) )
        {
            throw new ArchivaRestServiceException( "not authorized to delete artifacts", 403, null );
        }

        if ( StringUtils.isEmpty( namespace ) )
        {
            throw new ArchivaRestServiceException( "groupId cannot be null", 400, null );
        }

        if ( StringUtils.isEmpty( projectId ) )
        {
            throw new ArchivaRestServiceException( "artifactId cannot be null", 400, null );
        }

        if ( StringUtils.isEmpty( version ) )
        {
            throw new ArchivaRestServiceException( "version cannot be null", 400, null );
        }

        RepositorySession repositorySession = null;
        try
        {
            repositorySession = repositorySessionFactory.createSession();
        }
        catch ( MetadataRepositoryException e )
        {
            e.printStackTrace( );
        }

        try
        {
            ManagedRepositoryContent repository = getManagedRepositoryContent( repositoryId );

            VersionedReference ref = new VersionedReference();
            ref.setArtifactId( projectId );
            ref.setGroupId( namespace );
            ref.setVersion( version );

            repository.deleteVersion( ref );

            /*
            ProjectReference projectReference = new ProjectReference();
            projectReference.setGroupId( namespace );
            projectReference.setArtifactId( projectId );

            repository.getVersions(  )
            */

            ArtifactReference artifactReference = new ArtifactReference();
            artifactReference.setGroupId( namespace );
            artifactReference.setArtifactId( projectId );
            artifactReference.setVersion( version );

            MetadataRepository metadataRepository = repositorySession.getRepository();

            List<ArtifactReference> related = repository.getRelatedArtifacts( repository.toVersion(artifactReference) );
            log.debug( "related: {}", related );
            for ( ArtifactReference artifactRef : related )
            {
                repository.deleteArtifact( artifactRef );
            }

            Collection<ArtifactMetadata> artifacts =
                metadataRepository.getArtifacts(repositorySession , repositoryId, namespace, projectId, version );

            for ( ArtifactMetadata artifactMetadata : artifacts )
            {
                metadataRepository.removeTimestampedArtifact(repositorySession , artifactMetadata, version );
            }

            metadataRepository.removeProjectVersion(repositorySession , repositoryId, namespace, projectId, version );
        }
        catch ( MetadataRepositoryException | MetadataResolutionException | RepositoryException | LayoutException e )
        {
            throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
        }
        finally
        {

            try {
                repositorySession.save();
            } catch (MetadataSessionException e) {
                log.error("Session save failed {}", e.getMessage());
            }

            repositorySession.close();
        }


        return Boolean.TRUE;
    }

    @Override
    public Boolean deleteArtifact( Artifact artifact )
        throws ArchivaRestServiceException
    {

        String repositoryId = artifact.getContext();
        // some rest call can use context or repositoryId
        // so try both!!
        if ( StringUtils.isEmpty( repositoryId ) )
        {
            repositoryId = artifact.getRepositoryId();
        }
        if ( StringUtils.isEmpty( repositoryId ) )
        {
            throw new ArchivaRestServiceException( "repositoryId cannot be null", 400, null );
        }

        if ( !isAuthorizedToDeleteArtifacts( repositoryId ) )
        {
            throw new ArchivaRestServiceException( "not authorized to delete artifacts", 403, null );
        }

        if ( artifact == null )
        {
            throw new ArchivaRestServiceException( "artifact cannot be null", 400, null );
        }

        if ( StringUtils.isEmpty( artifact.getGroupId() ) )
        {
            throw new ArchivaRestServiceException( "artifact.groupId cannot be null", 400, null );
        }

        if ( StringUtils.isEmpty( artifact.getArtifactId() ) )
        {
            throw new ArchivaRestServiceException( "artifact.artifactId cannot be null", 400, null );
        }

        // TODO more control on artifact fields

        boolean snapshotVersion =
            VersionUtil.isSnapshot( artifact.getVersion() ) | VersionUtil.isGenericSnapshot( artifact.getVersion() );

        RepositorySession repositorySession = null;
        try
        {
            repositorySession = repositorySessionFactory.createSession();
        }
        catch ( MetadataRepositoryException e )
        {
            e.printStackTrace( );
        }
        try
        {
            Date lastUpdatedTimestamp = Calendar.getInstance().getTime();

            TimeZone timezone = TimeZone.getTimeZone( "UTC" );
            DateFormat fmt = new SimpleDateFormat( "yyyyMMdd.HHmmss" );
            fmt.setTimeZone( timezone );
            ManagedRepository repo = repositoryRegistry.getManagedRepository( repositoryId );

            VersionedReference ref = new VersionedReference();
            ref.setArtifactId( artifact.getArtifactId() );
            ref.setGroupId( artifact.getGroupId() );
            ref.setVersion( artifact.getVersion() );

            ManagedRepositoryContent repository = getManagedRepositoryContent( repositoryId );

            ArtifactReference artifactReference = new ArtifactReference();
            artifactReference.setArtifactId( artifact.getArtifactId() );
            artifactReference.setGroupId( artifact.getGroupId() );
            artifactReference.setVersion( artifact.getVersion() );
            artifactReference.setClassifier( artifact.getClassifier() );
            artifactReference.setType( artifact.getType() );

            MetadataRepository metadataRepository = repositorySession.getRepository();

            String path = repository.toMetadataPath( ref );

            if ( StringUtils.isNotBlank( artifact.getClassifier() ) )
            {
                if ( StringUtils.isBlank( artifact.getPackaging() ) )
                {
                    throw new ArchivaRestServiceException( "You must configure a type/packaging when using classifier",
                                                           400, null );
                }
                List<ArtifactReference> artifacts = repository.getRelatedArtifacts( artifactReference );
                for (ArtifactReference aRef : artifacts ) {
                    repository.deleteArtifact( aRef );
                }

            }
            else
            {

                int index = path.lastIndexOf( '/' );
                path = path.substring( 0, index );
                StorageAsset targetPath = repo.getAsset( path );

                if ( !targetPath.exists() )
                {
                    //throw new ContentNotFoundException(
                    //    artifact.getNamespace() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion() );
                    log.warn( "targetPath {} not found skip file deletion", targetPath );
                    return false;
                }

                // TODO: this should be in the storage mechanism so that it is all tied together
                // delete from file system
                if ( !snapshotVersion )
                {
                    repository.deleteVersion( ref );
                }
                else
                {
                    // We are deleting all version related artifacts for a snapshot version
                    VersionedReference versionRef = repository.toVersion( artifactReference );
                    List<ArtifactReference> related = repository.getRelatedArtifacts( versionRef );
                    log.debug( "related: {}", related );
                    for ( ArtifactReference artifactRef : related )
                    {
                        try
                        {
                            repository.deleteArtifact( artifactRef );
                        } catch (ContentNotFoundException e) {
                            log.warn( "Artifact that should be deleted, was not found: {}", artifactRef );
                        }
                    }
                    StorageAsset metadataFile = getMetadata( repo, targetPath.getPath() );
                    ArchivaRepositoryMetadata metadata = getMetadata( repository.getRepository().getType(), metadataFile );

                    updateMetadata( metadata, metadataFile, lastUpdatedTimestamp, artifact );
                }
            }
            Collection<ArtifactMetadata> artifacts = Collections.emptyList();

            if ( snapshotVersion )
            {
                String baseVersion = VersionUtil.getBaseVersion( artifact.getVersion() );
                artifacts =
                    metadataRepository.getArtifacts(repositorySession , repositoryId, artifact.getGroupId(),
                        artifact.getArtifactId(), baseVersion );
            }
            else
            {
                artifacts =
                    metadataRepository.getArtifacts(repositorySession , repositoryId, artifact.getGroupId(),
                        artifact.getArtifactId(), artifact.getVersion() );
            }

            log.debug( "artifacts: {}", artifacts );

            if ( artifacts.isEmpty() )
            {
                if ( !snapshotVersion )
                {
                    // verify metata repository doesn't contains anymore the version
                    Collection<String> projectVersions =
                        metadataRepository.getProjectVersions(repositorySession , repositoryId,
                            artifact.getGroupId(), artifact.getArtifactId() );

                    if ( projectVersions.contains( artifact.getVersion() ) )
                    {
                        log.warn( "artifact not found when deleted but version still here ! so force cleanup" );
                        metadataRepository.removeProjectVersion(repositorySession , repositoryId,
                            artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() );
                    }

                }
            }

            for ( ArtifactMetadata artifactMetadata : artifacts )
            {

                // TODO: mismatch between artifact (snapshot) version and project (base) version here
                if ( artifactMetadata.getVersion().equals( artifact.getVersion() ) )
                {
                    if ( StringUtils.isNotBlank( artifact.getClassifier() ) )
                    {
                        if ( StringUtils.isBlank( artifact.getPackaging() ) )
                        {
                            throw new ArchivaRestServiceException(
                                "You must configure a type/packaging when using classifier", 400, null );
                        }
                        // cleanup facet which contains classifier information
                        MavenArtifactFacet mavenArtifactFacet =
                            (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID );

                        if ( StringUtils.equals( artifact.getClassifier(), mavenArtifactFacet.getClassifier() ) )
                        {
                            artifactMetadata.removeFacet( MavenArtifactFacet.FACET_ID );
                            String groupId = artifact.getGroupId(), artifactId = artifact.getArtifactId(), version =
                                artifact.getVersion();
                            MavenArtifactFacet mavenArtifactFacetToCompare = new MavenArtifactFacet();
                            mavenArtifactFacetToCompare.setClassifier( artifact.getClassifier() );
                            metadataRepository.removeFacetFromArtifact(repositorySession , repositoryId, groupId, artifactId,
                                version, mavenArtifactFacetToCompare );
                            repositorySession.save();
                        }

                    }
                    else
                    {
                        if ( snapshotVersion )
                        {
                            metadataRepository.removeTimestampedArtifact(repositorySession ,
                                artifactMetadata, VersionUtil.getBaseVersion( artifact.getVersion() ) );
                        }
                        else
                        {
                            metadataRepository.removeArtifact(repositorySession ,
                                artifactMetadata.getRepositoryId(),
                                artifactMetadata.getNamespace(), artifactMetadata.getProject(),
                                artifact.getVersion(), artifactMetadata.getId() );
                        }
                    }
                    // TODO: move into the metadata repository proper - need to differentiate attachment of
                    //       repository metadata to an artifact
                    for ( RepositoryListener listener : listeners )
                    {
                        listener.deleteArtifact( metadataRepository, repository.getId(),
                                                 artifactMetadata.getNamespace(), artifactMetadata.getProject(),
                                                 artifactMetadata.getVersion(), artifactMetadata.getId() );
                    }

                    triggerAuditEvent( repositoryId, path, AuditEvent.REMOVE_FILE );
                }
            }
        }
        catch ( ContentNotFoundException e )
        {
            throw new ArchivaRestServiceException( "Artifact does not exist: " + e.getMessage(), 400, e );
        }
        catch ( RepositoryNotFoundException e )
        {
            throw new ArchivaRestServiceException( "Target repository cannot be found: " + e.getMessage(), 400, e );
        }
        catch ( RepositoryException e )
        {
            throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
        }
        catch (MetadataResolutionException | MetadataSessionException | MetadataRepositoryException | LayoutException e )
        {
            throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
        }
        finally
        {

            try {
                repositorySession.save();
            } catch (MetadataSessionException e) {
                log.error("Could not save sesion {}", e.getMessage());
            }

            repositorySession.close();
        }
        return Boolean.TRUE;
    }

    @Override
    public Boolean deleteGroupId( String groupId, String repositoryId )
        throws ArchivaRestServiceException
    {
        if ( StringUtils.isEmpty( repositoryId ) )
        {
            throw new ArchivaRestServiceException( "repositoryId cannot be null", 400, null );
        }

        if ( !isAuthorizedToDeleteArtifacts( repositoryId ) )
        {
            throw new ArchivaRestServiceException( "not authorized to delete artifacts", 403, null );
        }

        if ( StringUtils.isEmpty( groupId ) )
        {
            throw new ArchivaRestServiceException( "groupId cannot be null", 400, null );
        }

        RepositorySession repositorySession = null;
        try
        {
            repositorySession = repositorySessionFactory.createSession();
        }
        catch ( MetadataRepositoryException e )
        {
            e.printStackTrace( );
        }

        try
        {
            ManagedRepositoryContent repository = getManagedRepositoryContent( repositoryId );

            repository.deleteGroupId( groupId );

            MetadataRepository metadataRepository = repositorySession.getRepository();

            metadataRepository.removeNamespace(repositorySession , repositoryId, groupId );

            // just invalidate cache entry
            String cacheKey = repositoryId + "-" + groupId;
            namespacesCache.remove( cacheKey );
            namespacesCache.remove( repositoryId );

            repositorySession.save();
        }
        catch (MetadataRepositoryException | MetadataSessionException e )
        {
            log.error( e.getMessage(), e );
            throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
        }
        catch ( RepositoryException e )
        {
            log.error( e.getMessage(), e );
            throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
        }
        finally
        {

            repositorySession.close();
        }
        return true;
    }

    @Override
    public Boolean deleteProject( String groupId, String projectId, String repositoryId )
        throws ArchivaRestServiceException
    {
        if ( StringUtils.isEmpty( repositoryId ) )
        {
            throw new ArchivaRestServiceException( "repositoryId cannot be null", 400, null );
        }

        if ( !isAuthorizedToDeleteArtifacts( repositoryId ) )
        {
            throw new ArchivaRestServiceException( "not authorized to delete artifacts", 403, null );
        }

        if ( StringUtils.isEmpty( groupId ) )
        {
            throw new ArchivaRestServiceException( "groupId cannot be null", 400, null );
        }

        if ( StringUtils.isEmpty( projectId ) )
        {
            throw new ArchivaRestServiceException( "artifactId cannot be null", 400, null );
        }

        RepositorySession repositorySession = null;
        try
        {
            repositorySession = repositorySessionFactory.createSession();
        }
        catch ( MetadataRepositoryException e )
        {
            e.printStackTrace( );
        }

        try
        {
            ManagedRepositoryContent repository = getManagedRepositoryContent( repositoryId );

            repository.deleteProject( groupId, projectId );
        }
        catch ( ContentNotFoundException e )
        {
            log.warn( "skip ContentNotFoundException: {}", e.getMessage() );
        }
        catch ( RepositoryException e )
        {
            log.error( e.getMessage(), e );
            throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
        }

        try
        {

            MetadataRepository metadataRepository = repositorySession.getRepository();

            metadataRepository.removeProject(repositorySession , repositoryId, groupId, projectId );

            repositorySession.save();
        }
        catch (MetadataRepositoryException | MetadataSessionException e )
        {
            log.error( e.getMessage(), e );
            throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
        }
        finally
        {

            repositorySession.close();
        }
        return true;

    }

    @Override
    public Boolean isAuthorizedToDeleteArtifacts( String repoId )
        throws ArchivaRestServiceException
    {
        String userName =
            getAuditInformation().getUser() == null ? "guest" : getAuditInformation().getUser().getUsername();

        try
        {
            return userRepositories.isAuthorizedToDeleteArtifacts( userName, repoId );
        }
        catch ( ArchivaSecurityException e )
        {
            throw new ArchivaRestServiceException( e.getMessage(),
                                                   Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
        }
    }

    @Override
    public RepositoryScanStatistics scanRepositoryDirectoriesNow( String repositoryId )
        throws ArchivaRestServiceException
    {
        long sinceWhen = RepositoryScanner.FRESH_SCAN;
        try
        {
            return repoScanner.scan( repositoryRegistry.getManagedRepository( repositoryId ), sinceWhen );
        }
        catch ( RepositoryScannerException e )
        {
            log.error( e.getMessage(), e );
            throw new ArchivaRestServiceException( "RepositoryScannerException exception: " + e.getMessage(), 500, e );
        }
    }

    /**
     * Update artifact level metadata. Creates one if metadata does not exist after artifact deletion.
     *
     * @param metadata
     */
    private void updateMetadata( ArchivaRepositoryMetadata metadata, StorageAsset metadataFile, Date lastUpdatedTimestamp,
                                 Artifact artifact )
        throws RepositoryMetadataException
    {
        List<String> availableVersions = new ArrayList<>();
        String latestVersion = "";

        if ( metadataFile.exists() )
        {
            if ( metadata.getAvailableVersions() != null )
            {
                availableVersions = metadata.getAvailableVersions();

                if ( availableVersions.size() > 0 )
                {
                    Collections.sort( availableVersions, VersionComparator.getInstance() );

                    if ( availableVersions.contains( artifact.getVersion() ) )
                    {
                        availableVersions.remove( availableVersions.indexOf( artifact.getVersion() ) );
                    }
                    if ( availableVersions.size() > 0 )
                    {
                        latestVersion = availableVersions.get( availableVersions.size() - 1 );
                    }
                }
            }
        }

        if ( metadata.getGroupId() == null )
        {
            metadata.setGroupId( artifact.getGroupId() );
        }
        if ( metadata.getArtifactId() == null )
        {
            metadata.setArtifactId( artifact.getArtifactId() );
        }

        if ( !VersionUtil.isSnapshot( artifact.getVersion() ) )
        {
            if ( metadata.getReleasedVersion() != null && metadata.getReleasedVersion().equals(
                artifact.getVersion() ) )
            {
                metadata.setReleasedVersion( latestVersion );
            }
        }

        metadata.setLatestVersion( latestVersion );
        metadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
        metadata.setAvailableVersions( availableVersions );

        try (OutputStreamWriter writer = new OutputStreamWriter(metadataFile.getWriteStream(true))) {
            RepositoryMetadataWriter.write(metadata, writer);
        } catch (IOException e) {
            throw new RepositoryMetadataException(e);
        }
        ChecksummedFile checksum = new ChecksummedFile( metadataFile.getFilePath() );
        checksum.fixChecksums( algorithms );
    }

    @Override
    public StringList getRunningRemoteDownloadIds()
    {
        return new StringList( downloadRemoteIndexScheduler.getRunningRemoteDownloadIds() );
    }

    public RepositorySessionFactory getRepositorySessionFactory()
    {
        return repositorySessionFactory;
    }

    public void setRepositorySessionFactory( RepositorySessionFactory repositorySessionFactory )
    {
        this.repositorySessionFactory = repositorySessionFactory;
    }

    public List<RepositoryListener> getListeners()
    {
        return listeners;
    }

    public void setListeners( List<RepositoryListener> listeners )
    {
        this.listeners = listeners;
    }

    public ArchivaAdministration getArchivaAdministration()
    {
        return archivaAdministration;
    }

    public void setArchivaAdministration( ArchivaAdministration archivaAdministration )
    {
        this.archivaAdministration = archivaAdministration;
    }
}


