package org.apache.archiva.metadata.repository.storage.maven2;

/*
 * 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.beans.ManagedRepository;
import org.apache.archiva.admin.model.beans.NetworkProxy;
import org.apache.archiva.admin.model.beans.ProxyConnector;
import org.apache.archiva.admin.model.beans.RemoteRepository;
import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
import org.apache.archiva.admin.model.networkproxy.NetworkProxyAdmin;
import org.apache.archiva.admin.model.proxyconnector.ProxyConnectorAdmin;
import org.apache.archiva.admin.model.remote.RemoteRepositoryAdmin;
import org.apache.archiva.checksum.ChecksumAlgorithm;
import org.apache.archiva.checksum.ChecksummedFile;
import org.apache.archiva.common.utils.VersionUtil;
import org.apache.archiva.maven2.metadata.MavenMetadataReader;
import org.apache.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.model.ProjectMetadata;
import org.apache.archiva.metadata.model.ProjectVersionMetadata;
import org.apache.archiva.metadata.model.facets.RepositoryProblemFacet;
import org.apache.archiva.metadata.repository.filter.Filter;
import org.apache.archiva.metadata.repository.storage.ReadMetadataRequest;
import org.apache.archiva.metadata.repository.storage.RelocationException;
import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator;
import org.apache.archiva.metadata.repository.storage.RepositoryStorage;
import org.apache.archiva.metadata.repository.storage.RepositoryStorageMetadataInvalidException;
import org.apache.archiva.metadata.repository.storage.RepositoryStorageMetadataNotFoundException;
import org.apache.archiva.metadata.repository.storage.RepositoryStorageRuntimeException;
import org.apache.archiva.model.ArchivaRepositoryMetadata;
import org.apache.archiva.model.ArtifactReference;
import org.apache.archiva.model.SnapshotVersion;
import org.apache.archiva.policies.ProxyDownloadException;
import org.apache.archiva.proxy.common.WagonFactory;
import org.apache.archiva.proxy.model.RepositoryProxyConnectors;
import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.content.PathParser;
import org.apache.archiva.repository.layout.LayoutException;
import org.apache.archiva.xml.XMLException;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.model.CiManagement;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DistributionManagement;
import org.apache.maven.model.IssueManagement;
import org.apache.maven.model.License;
import org.apache.maven.model.MailingList;
import org.apache.maven.model.Model;
import org.apache.maven.model.Organization;
import org.apache.maven.model.Relocation;
import org.apache.maven.model.Scm;
import org.apache.maven.model.building.DefaultModelBuilderFactory;
import org.apache.maven.model.building.DefaultModelBuildingRequest;
import org.apache.maven.model.building.ModelBuilder;
import org.apache.maven.model.building.ModelBuildingException;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.ModelProblem;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.Reader;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Maven 2 repository format storage implementation. This class currently takes parameters to indicate the repository to
 * deal with rather than being instantiated per-repository.
 * FIXME: instantiate one per repository and allocate permanently from a factory (which can be obtained within the session).
 * <p/>
 * The session is passed in as an argument to obtain any necessary resources, rather than the class being instantiated
 * within the session in the context of a single managed repository's resolution needs.
 * <p/>
 */
@Service( "repositoryStorage#maven2" )
public class Maven2RepositoryStorage
    implements RepositoryStorage
{

    private static final Logger LOGGER = LoggerFactory.getLogger( Maven2RepositoryStorage.class );

    private ModelBuilder builder;

    @Inject
    private RemoteRepositoryAdmin remoteRepositoryAdmin;

    @Inject
    private ManagedRepositoryAdmin managedRepositoryAdmin;

    @Inject
    private ProxyConnectorAdmin proxyConnectorAdmin;

    @Inject
    private NetworkProxyAdmin networkProxyAdmin;

    @Inject
    @Named( "repositoryPathTranslator#maven2" )
    private RepositoryPathTranslator pathTranslator;

    @Inject
    private WagonFactory wagonFactory;

    @Inject
    private ApplicationContext applicationContext;

    @Inject
    @Named( "pathParser#default" )
    private PathParser pathParser;

    private static final String METADATA_FILENAME_START = "maven-metadata";

    private static final String METADATA_FILENAME = METADATA_FILENAME_START + ".xml";

    private static final MavenXpp3Reader MAVEN_XPP_3_READER = new MavenXpp3Reader();


    @PostConstruct
    public void initialize()
    {
        builder = new DefaultModelBuilderFactory().newInstance();

    }

    @Override
    public ProjectMetadata readProjectMetadata( String repoId, String namespace, String projectId )
    {
        // TODO: could natively implement the "shared model" concept from the browse action to avoid needing it there?
        return null;
    }

    @Override
    public ProjectVersionMetadata readProjectVersionMetadata( ReadMetadataRequest readMetadataRequest )
        throws RepositoryStorageMetadataNotFoundException, RepositoryStorageMetadataInvalidException,
        RepositoryStorageRuntimeException
    {
        try
        {
            ManagedRepository managedRepository =
                managedRepositoryAdmin.getManagedRepository( readMetadataRequest.getRepositoryId() );
            String artifactVersion = readMetadataRequest.getProjectVersion();
            // olamy: in case of browsing via the ui we can mix repos (parent of a SNAPSHOT can come from release repo)
            if ( !readMetadataRequest.isBrowsingRequest() )
            {
                if ( VersionUtil.isSnapshot( artifactVersion ) )
                {
                    // skygo trying to improve speed by honoring managed configuration MRM-1658
                    if ( managedRepository.isReleases() && !managedRepository.isSnapshots() )
                    {
                        throw new RepositoryStorageRuntimeException( "lookforsnaponreleaseonly",
                                                                     "managed repo is configured for release only" );
                    }
                }
                else
                {
                    if ( !managedRepository.isReleases() && managedRepository.isSnapshots() )
                    {
                        throw new RepositoryStorageRuntimeException( "lookforsreleaseonsneponly",
                                                                     "managed repo is configured for snapshot only" );
                    }
                }
            }
            File basedir = new File( managedRepository.getLocation() );
            if ( VersionUtil.isSnapshot( artifactVersion ) )
            {
                File metadataFile = pathTranslator.toFile( basedir, readMetadataRequest.getNamespace(),
                                                           readMetadataRequest.getProjectId(), artifactVersion,
                                                           METADATA_FILENAME );
                try
                {
                    ArchivaRepositoryMetadata metadata = MavenMetadataReader.read( metadataFile );

                    // re-adjust to timestamp if present, otherwise retain the original -SNAPSHOT filename
                    SnapshotVersion snapshotVersion = metadata.getSnapshotVersion();
                    if ( snapshotVersion != null )
                    {
                        artifactVersion =
                            artifactVersion.substring( 0, artifactVersion.length() - 8 ); // remove SNAPSHOT from end
                        artifactVersion =
                            artifactVersion + snapshotVersion.getTimestamp() + "-" + snapshotVersion.getBuildNumber();
                    }
                }
                catch ( XMLException e )
                {
                    // unable to parse metadata - LOGGER it, and continue with the version as the original SNAPSHOT version
                    LOGGER.warn( "Invalid metadata: {} - {}", metadataFile, e.getMessage() );
                }
            }

            // TODO: won't work well with some other layouts, might need to convert artifact parts to ID by path translator
            String id = readMetadataRequest.getProjectId() + "-" + artifactVersion + ".pom";
            File file =
                pathTranslator.toFile( basedir, readMetadataRequest.getNamespace(), readMetadataRequest.getProjectId(),
                                       readMetadataRequest.getProjectVersion(), id );

            if ( !file.exists() )
            {
                // metadata could not be resolved
                throw new RepositoryStorageMetadataNotFoundException(
                    "The artifact's POM file '" + file.getAbsolutePath() + "' was missing" );
            }

            // TODO: this is a workaround until we can properly resolve using proxies as well - this doesn't cache
            //       anything locally!
            List<RemoteRepository> remoteRepositories = new ArrayList<>();
            Map<String, NetworkProxy> networkProxies = new HashMap<>();

            Map<String, List<ProxyConnector>> proxyConnectorsMap = proxyConnectorAdmin.getProxyConnectorAsMap();
            List<ProxyConnector> proxyConnectors = proxyConnectorsMap.get( readMetadataRequest.getRepositoryId() );
            if ( proxyConnectors != null )
            {
                for ( ProxyConnector proxyConnector : proxyConnectors )
                {
                    RemoteRepository remoteRepoConfig =
                        remoteRepositoryAdmin.getRemoteRepository( proxyConnector.getTargetRepoId() );

                    if ( remoteRepoConfig != null )
                    {
                        remoteRepositories.add( remoteRepoConfig );

                        NetworkProxy networkProxyConfig =
                            networkProxyAdmin.getNetworkProxy( proxyConnector.getProxyId() );

                        if ( networkProxyConfig != null )
                        {
                            // key/value: remote repo ID/proxy info
                            networkProxies.put( proxyConnector.getTargetRepoId(), networkProxyConfig );
                        }
                    }
                }
            }

            // That's a browsing request so we can a mix of SNAPSHOT and release artifacts (especially with snapshots which
            // can have released parent pom
            if ( readMetadataRequest.isBrowsingRequest() )
            {
                remoteRepositories.addAll( remoteRepositoryAdmin.getRemoteRepositories() );
            }

            ModelBuildingRequest req =
                new DefaultModelBuildingRequest().setProcessPlugins( false ).setPomFile( file ).setTwoPhaseBuilding(
                    false ).setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );

            //MRM-1607. olamy this will resolve jdk profiles on the current running archiva jvm
            req.setSystemProperties( System.getProperties() );

            // MRM-1411
            req.setModelResolver(
                new RepositoryModelResolver( managedRepository, pathTranslator, wagonFactory, remoteRepositories,
                                             networkProxies, managedRepository ) );

            Model model;
            try
            {
                model = builder.build( req ).getEffectiveModel();
            }
            catch ( ModelBuildingException e )
            {
                String msg = "The artifact's POM file '" + file + "' was invalid: " + e.getMessage();

                List<ModelProblem> modelProblems = e.getProblems();
                for ( ModelProblem problem : modelProblems )
                {
                    // MRM-1411, related to MRM-1335
                    // this means that the problem was that the parent wasn't resolved!
                    // olamy really hackhish but fail with java profile so use error message
                    // || ( StringUtils.startsWith( problem.getMessage(), "Failed to determine Java version for profile" ) )
                    // but setTwoPhaseBuilding(true) fix that
                    if ( ( problem.getException() instanceof FileNotFoundException && e.getModelId() != null &&
                        !e.getModelId().equals( problem.getModelId() ) ) )
                    {
                        LOGGER.warn( "The artifact's parent POM file '{}' cannot be resolved. "
                                         + "Using defaults for project version metadata..", file );

                        ProjectVersionMetadata metadata = new ProjectVersionMetadata();
                        metadata.setId( readMetadataRequest.getProjectVersion() );

                        MavenProjectFacet facet = new MavenProjectFacet();
                        facet.setGroupId( readMetadataRequest.getNamespace() );
                        facet.setArtifactId( readMetadataRequest.getProjectId() );
                        facet.setPackaging( "jar" );
                        metadata.addFacet( facet );

                        String errMsg =
                            "Error in resolving artifact's parent POM file. " + ( problem.getException() == null
                                ? problem.getMessage()
                                : problem.getException().getMessage() );
                        RepositoryProblemFacet repoProblemFacet = new RepositoryProblemFacet();
                        repoProblemFacet.setRepositoryId( readMetadataRequest.getRepositoryId() );
                        repoProblemFacet.setId( readMetadataRequest.getRepositoryId() );
                        repoProblemFacet.setMessage( errMsg );
                        repoProblemFacet.setProblem( errMsg );
                        repoProblemFacet.setProject( readMetadataRequest.getProjectId() );
                        repoProblemFacet.setVersion( readMetadataRequest.getProjectVersion() );
                        repoProblemFacet.setNamespace( readMetadataRequest.getNamespace() );

                        metadata.addFacet( repoProblemFacet );

                        return metadata;
                    }
                }

                throw new RepositoryStorageMetadataInvalidException( "invalid-pom", msg, e );
            }

            // Check if the POM is in the correct location
            boolean correctGroupId = readMetadataRequest.getNamespace().equals( model.getGroupId() );
            boolean correctArtifactId = readMetadataRequest.getProjectId().equals( model.getArtifactId() );
            boolean correctVersion = readMetadataRequest.getProjectVersion().equals( model.getVersion() );
            if ( !correctGroupId || !correctArtifactId || !correctVersion )
            {
                StringBuilder message = new StringBuilder( "Incorrect POM coordinates in '" + file + "':" );
                if ( !correctGroupId )
                {
                    message.append( "\nIncorrect group ID: " ).append( model.getGroupId() );
                }
                if ( !correctArtifactId )
                {
                    message.append( "\nIncorrect artifact ID: " ).append( model.getArtifactId() );
                }
                if ( !correctVersion )
                {
                    message.append( "\nIncorrect version: " ).append( model.getVersion() );
                }

                throw new RepositoryStorageMetadataInvalidException( "mislocated-pom", message.toString() );
            }

            ProjectVersionMetadata metadata = new ProjectVersionMetadata();
            metadata.setCiManagement( convertCiManagement( model.getCiManagement() ) );
            metadata.setDescription( model.getDescription() );
            metadata.setId( readMetadataRequest.getProjectVersion() );
            metadata.setIssueManagement( convertIssueManagement( model.getIssueManagement() ) );
            metadata.setLicenses( convertLicenses( model.getLicenses() ) );
            metadata.setMailingLists( convertMailingLists( model.getMailingLists() ) );
            metadata.setDependencies( convertDependencies( model.getDependencies() ) );
            metadata.setName( model.getName() );
            metadata.setOrganization( convertOrganization( model.getOrganization() ) );
            metadata.setScm( convertScm( model.getScm() ) );
            metadata.setUrl( model.getUrl() );
            metadata.setProperties( model.getProperties() );

            MavenProjectFacet facet = new MavenProjectFacet();
            facet.setGroupId( model.getGroupId() != null ? model.getGroupId() : model.getParent().getGroupId() );
            facet.setArtifactId( model.getArtifactId() );
            facet.setPackaging( model.getPackaging() );
            if ( model.getParent() != null )
            {
                MavenProjectParent parent = new MavenProjectParent();
                parent.setGroupId( model.getParent().getGroupId() );
                parent.setArtifactId( model.getParent().getArtifactId() );
                parent.setVersion( model.getParent().getVersion() );
                facet.setParent( parent );
            }
            metadata.addFacet( facet );

            return metadata;
        }
        catch ( RepositoryAdminException e )
        {
            throw new RepositoryStorageRuntimeException( "repo-admin", e.getMessage(), e );
        }
    }

    public void setWagonFactory( WagonFactory wagonFactory )
    {
        this.wagonFactory = wagonFactory;
    }

    private List<org.apache.archiva.metadata.model.Dependency> convertDependencies( List<Dependency> dependencies )
    {
        List<org.apache.archiva.metadata.model.Dependency> l = new ArrayList<>();
        for ( Dependency dependency : dependencies )
        {
            org.apache.archiva.metadata.model.Dependency newDependency =
                new org.apache.archiva.metadata.model.Dependency();
            newDependency.setArtifactId( dependency.getArtifactId() );
            newDependency.setClassifier( dependency.getClassifier() );
            newDependency.setGroupId( dependency.getGroupId() );
            newDependency.setOptional( dependency.isOptional() );
            newDependency.setScope( dependency.getScope() );
            newDependency.setSystemPath( dependency.getSystemPath() );
            newDependency.setType( dependency.getType() );
            newDependency.setVersion( dependency.getVersion() );
            l.add( newDependency );
        }
        return l;
    }

    private org.apache.archiva.metadata.model.Scm convertScm( Scm scm )
    {
        org.apache.archiva.metadata.model.Scm newScm = null;
        if ( scm != null )
        {
            newScm = new org.apache.archiva.metadata.model.Scm();
            newScm.setConnection( scm.getConnection() );
            newScm.setDeveloperConnection( scm.getDeveloperConnection() );
            newScm.setUrl( scm.getUrl() );
        }
        return newScm;
    }

    private org.apache.archiva.metadata.model.Organization convertOrganization( Organization organization )
    {
        org.apache.archiva.metadata.model.Organization org = null;
        if ( organization != null )
        {
            org = new org.apache.archiva.metadata.model.Organization();
            org.setName( organization.getName() );
            org.setUrl( organization.getUrl() );
        }
        return org;
    }

    private List<org.apache.archiva.metadata.model.License> convertLicenses( List<License> licenses )
    {
        List<org.apache.archiva.metadata.model.License> l = new ArrayList<>();
        for ( License license : licenses )
        {
            org.apache.archiva.metadata.model.License newLicense = new org.apache.archiva.metadata.model.License();
            newLicense.setName( license.getName() );
            newLicense.setUrl( license.getUrl() );
            l.add( newLicense );
        }
        return l;
    }

    private List<org.apache.archiva.metadata.model.MailingList> convertMailingLists( List<MailingList> mailingLists )
    {
        List<org.apache.archiva.metadata.model.MailingList> l = new ArrayList<>();
        for ( MailingList mailingList : mailingLists )
        {
            org.apache.archiva.metadata.model.MailingList newMailingList =
                new org.apache.archiva.metadata.model.MailingList();
            newMailingList.setName( mailingList.getName() );
            newMailingList.setMainArchiveUrl( mailingList.getArchive() );
            newMailingList.setPostAddress( mailingList.getPost() );
            newMailingList.setSubscribeAddress( mailingList.getSubscribe() );
            newMailingList.setUnsubscribeAddress( mailingList.getUnsubscribe() );
            newMailingList.setOtherArchives( mailingList.getOtherArchives() );
            l.add( newMailingList );
        }
        return l;
    }

    private org.apache.archiva.metadata.model.IssueManagement convertIssueManagement( IssueManagement issueManagement )
    {
        org.apache.archiva.metadata.model.IssueManagement im = null;
        if ( issueManagement != null )
        {
            im = new org.apache.archiva.metadata.model.IssueManagement();
            im.setSystem( issueManagement.getSystem() );
            im.setUrl( issueManagement.getUrl() );
        }
        return im;
    }

    private org.apache.archiva.metadata.model.CiManagement convertCiManagement( CiManagement ciManagement )
    {
        org.apache.archiva.metadata.model.CiManagement ci = null;
        if ( ciManagement != null )
        {
            ci = new org.apache.archiva.metadata.model.CiManagement();
            ci.setSystem( ciManagement.getSystem() );
            ci.setUrl( ciManagement.getUrl() );
        }
        return ci;
    }

    @Override
    public Collection<String> listRootNamespaces( String repoId, Filter<String> filter )
        throws RepositoryStorageRuntimeException
    {
        File dir = getRepositoryBasedir( repoId );

        return getSortedFiles( dir, filter );
    }

    private static Collection<String> getSortedFiles( File dir, Filter<String> filter )
    {
        List<String> fileNames;
        String[] files = dir.list( new DirectoryFilter( filter ) );
        if ( files != null )
        {
            fileNames = new ArrayList<>( Arrays.asList( files ) );
            Collections.sort( fileNames );
        }
        else
        {
            fileNames = Collections.emptyList();
        }
        return fileNames;
    }

    private File getRepositoryBasedir( String repoId )
        throws RepositoryStorageRuntimeException
    {
        try
        {
            ManagedRepository repositoryConfiguration = managedRepositoryAdmin.getManagedRepository( repoId );

            return new File( repositoryConfiguration.getLocation() );
        }
        catch ( RepositoryAdminException e )
        {
            throw new RepositoryStorageRuntimeException( "repo-admin", e.getMessage(), e );
        }
    }

    @Override
    public Collection<String> listNamespaces( String repoId, String namespace, Filter<String> filter )
        throws RepositoryStorageRuntimeException
    {
        File dir = pathTranslator.toFile( getRepositoryBasedir( repoId ), namespace );

        // scan all the directories which are potential namespaces. Any directories known to be projects are excluded
        List<String> namespaces = new ArrayList<>();
        File[] files = dir.listFiles( new DirectoryFilter( filter ) );
        if ( files != null )
        {
            for ( File file : files )
            {
                if ( !isProject( file, filter ) )
                {
                    namespaces.add( file.getName() );
                }
            }
        }
        Collections.sort( namespaces );
        return namespaces;
    }

    @Override
    public Collection<String> listProjects( String repoId, String namespace, Filter<String> filter )
        throws RepositoryStorageRuntimeException
    {
        File dir = pathTranslator.toFile( getRepositoryBasedir( repoId ), namespace );

        // scan all directories in the namespace, and only include those that are known to be projects
        List<String> projects = new ArrayList<>();

        File[] files = dir.listFiles( new DirectoryFilter( filter ) );
        if ( files != null )
        {
            for ( File file : files )
            {
                if ( isProject( file, filter ) )
                {
                    projects.add( file.getName() );
                }
            }
        }
        Collections.sort( projects );
        return projects;
    }

    @Override
    public Collection<String> listProjectVersions( String repoId, String namespace, String projectId,
                                                   Filter<String> filter )
        throws RepositoryStorageRuntimeException
    {
        File dir = pathTranslator.toFile( getRepositoryBasedir( repoId ), namespace, projectId );

        // all directories in a project directory can be considered a version
        return getSortedFiles( dir, filter );
    }

    @Override
    public Collection<ArtifactMetadata> readArtifactsMetadata( ReadMetadataRequest readMetadataRequest )
        throws RepositoryStorageRuntimeException
    {
        File dir = pathTranslator.toFile( getRepositoryBasedir( readMetadataRequest.getRepositoryId() ),
                                          readMetadataRequest.getNamespace(), readMetadataRequest.getProjectId(),
                                          readMetadataRequest.getProjectVersion() );

        // all files that are not metadata and not a checksum / signature are considered artifacts
        File[] files = dir.listFiles( new ArtifactDirectoryFilter( readMetadataRequest.getFilter() ) );

        List<ArtifactMetadata> artifacts = new ArrayList<>();
        if ( files != null )
        {
            for ( File file : files )
            {
                ArtifactMetadata metadata =
                    getArtifactFromFile( readMetadataRequest.getRepositoryId(), readMetadataRequest.getNamespace(),
                                         readMetadataRequest.getProjectId(), readMetadataRequest.getProjectVersion(),
                                         file );
                artifacts.add( metadata );
            }
        }
        return artifacts;
    }

    @Override
    public ArtifactMetadata readArtifactMetadataFromPath( String repoId, String path )
        throws RepositoryStorageRuntimeException
    {
        ArtifactMetadata metadata = pathTranslator.getArtifactForPath( repoId, path );

        populateArtifactMetadataFromFile( metadata, new File( getRepositoryBasedir( repoId ), path ) );

        return metadata;
    }

    private ArtifactMetadata getArtifactFromFile( String repoId, String namespace, String projectId,
                                                  String projectVersion, File file )
    {
        ArtifactMetadata metadata =
            pathTranslator.getArtifactFromId( repoId, namespace, projectId, projectVersion, file.getName() );

        populateArtifactMetadataFromFile( metadata, file );

        return metadata;
    }

    @Override
    public void applyServerSideRelocation( ManagedRepositoryContent managedRepository, ArtifactReference artifact )
        throws ProxyDownloadException
    {
        if ( "pom".equals( artifact.getType() ) )
        {
            return;
        }

        // Build the artifact POM reference
        ArtifactReference pomReference = new ArtifactReference();
        pomReference.setGroupId( artifact.getGroupId() );
        pomReference.setArtifactId( artifact.getArtifactId() );
        pomReference.setVersion( artifact.getVersion() );
        pomReference.setType( "pom" );

        RepositoryProxyConnectors connectors =
            applicationContext.getBean( "repositoryProxyConnectors#default", RepositoryProxyConnectors.class );

        // Get the artifact POM from proxied repositories if needed
        connectors.fetchFromProxies( managedRepository, pomReference );

        // Open and read the POM from the managed repo
        File pom = managedRepository.toFile( pomReference );

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

        try
        {
            // MavenXpp3Reader leaves the file open, so we need to close it ourselves.

            Model model = null;
            try (Reader reader = Files.newBufferedReader( pom.toPath(), Charset.defaultCharset() ))
            {
                model = MAVEN_XPP_3_READER.read( reader );
            }

            DistributionManagement dist = model.getDistributionManagement();
            if ( dist != null )
            {
                Relocation relocation = dist.getRelocation();
                if ( relocation != null )
                {
                    // artifact is relocated : update the repositoryPath
                    if ( relocation.getGroupId() != null )
                    {
                        artifact.setGroupId( relocation.getGroupId() );
                    }
                    if ( relocation.getArtifactId() != null )
                    {
                        artifact.setArtifactId( relocation.getArtifactId() );
                    }
                    if ( relocation.getVersion() != null )
                    {
                        artifact.setVersion( relocation.getVersion() );
                    }
                }
            }
        }
        catch ( IOException e )
        {
            // Unable to read POM : ignore.
        }
        catch ( XmlPullParserException e )
        {
            // Invalid POM : ignore
        }
    }


    @Override
    public String getFilePath( String requestPath, ManagedRepository managedRepository )
    {
        // managedRepository can be null
        // extract artifact reference from url
        // groupId:artifactId:version:packaging:classifier
        //org/apache/archiva/archiva-checksum/1.4-M4-SNAPSHOT/archiva-checksum-1.4-M4-SNAPSHOT.jar
        String logicalResource = null;
        String requestPathInfo = StringUtils.defaultString( requestPath );

        //remove prefix ie /repository/blah becomes /blah
        requestPathInfo = removePrefix( requestPathInfo );

        // Remove prefixing slash as the repository id doesn't contain it;
        if ( requestPathInfo.startsWith( "/" ) )
        {
            requestPathInfo = requestPathInfo.substring( 1 );
        }

        int slash = requestPathInfo.indexOf( '/' );
        if ( slash > 0 )
        {
            logicalResource = requestPathInfo.substring( slash );

            if ( logicalResource.endsWith( "/.." ) )
            {
                logicalResource += "/";
            }

            if ( logicalResource != null && logicalResource.startsWith( "//" ) )
            {
                logicalResource = logicalResource.substring( 1 );
            }

            if ( logicalResource == null )
            {
                logicalResource = "/";
            }
        }
        else
        {
            logicalResource = "/";
        }
        return logicalResource;

    }

    @Override
    public String getFilePathWithVersion( final String requestPath, ManagedRepositoryContent managedRepositoryContent )
        throws XMLException, RelocationException
    {

        if ( StringUtils.endsWith( requestPath, METADATA_FILENAME ) )
        {
            return getFilePath( requestPath, managedRepositoryContent.getRepository() );
        }

        String filePath = getFilePath( requestPath, managedRepositoryContent.getRepository() );

        ArtifactReference artifactReference = null;
        try
        {
            artifactReference = pathParser.toArtifactReference( filePath );
        }
        catch ( LayoutException e )
        {
            return filePath;
        }

        if ( StringUtils.endsWith( artifactReference.getVersion(), VersionUtil.SNAPSHOT ) )
        {
            // read maven metadata to get last timestamp
            File metadataDir = new File( managedRepositoryContent.getRepoRoot(), filePath ).getParentFile();
            if ( !metadataDir.exists() )
            {
                return filePath;
            }
            File metadataFile = new File( metadataDir, METADATA_FILENAME );
            if ( !metadataFile.exists() )
            {
                return filePath;
            }
            ArchivaRepositoryMetadata archivaRepositoryMetadata = MavenMetadataReader.read( metadataFile );
            int buildNumber = archivaRepositoryMetadata.getSnapshotVersion().getBuildNumber();
            String timestamp = archivaRepositoryMetadata.getSnapshotVersion().getTimestamp();

            // MRM-1846
            if ( buildNumber < 1 && timestamp == null )
            {
                return filePath;
            }

            // org/apache/archiva/archiva-checksum/1.4-M4-SNAPSHOT/archiva-checksum-1.4-M4-SNAPSHOT.jar
            // ->  archiva-checksum-1.4-M4-20130425.081822-1.jar

            filePath = StringUtils.replace( filePath, //
                                            artifactReference.getArtifactId() //
                                                + "-" + artifactReference.getVersion(), //
                                            artifactReference.getArtifactId() //
                                                + "-" + StringUtils.remove( artifactReference.getVersion(),
                                                                            "-" + VersionUtil.SNAPSHOT ) //
                                                + "-" + timestamp //
                                                + "-" + buildNumber );

            throw new RelocationException( "/repository/" + managedRepositoryContent.getRepository().getId() +
                                               ( StringUtils.startsWith( filePath, "/" ) ? "" : "/" ) + filePath,
                                           RelocationException.RelocationType.TEMPORARY );

        }

        return filePath;
    }

    //-----------------------------
    // internal
    //-----------------------------

    /**
     * FIXME remove
     *
     * @param href
     * @return
     */
    private static String removePrefix( final String href )
    {
        String[] parts = StringUtils.split( href, '/' );
        parts = (String[]) ArrayUtils.subarray( parts, 1, parts.length );
        if ( parts == null || parts.length == 0 )
        {
            return "/";
        }

        String joinedString = StringUtils.join( parts, '/' );
        if ( href.endsWith( "/" ) )
        {
            joinedString = joinedString + "/";
        }

        return joinedString;
    }

    private static void populateArtifactMetadataFromFile( ArtifactMetadata metadata, File file )
    {
        metadata.setWhenGathered( new Date() );
        metadata.setFileLastModified( file.lastModified() );
        ChecksummedFile checksummedFile = new ChecksummedFile( file );
        try
        {
            metadata.setMd5( checksummedFile.calculateChecksum( ChecksumAlgorithm.MD5 ) );
        }
        catch ( IOException e )
        {
            LOGGER.error( "Unable to checksum file {}: {},MD5", file, e.getMessage() );
        }
        try
        {
            metadata.setSha1( checksummedFile.calculateChecksum( ChecksumAlgorithm.SHA1 ) );
        }
        catch ( IOException e )
        {
            LOGGER.error( "Unable to checksum file {}: {},SHA1", file, e.getMessage() );
        }
        metadata.setSize( file.length() );
    }

    private boolean isProject( File dir, Filter<String> filter )
    {
        // scan directories for a valid project version subdirectory, meaning this must be a project directory
        File[] files = dir.listFiles( new DirectoryFilter( filter ) );
        if ( files != null )
        {
            for ( File file : files )
            {
                if ( isProjectVersion( file ) )
                {
                    return true;
                }
            }
        }

        // if a metadata file is present, check if this is the "artifactId" directory, marking it as a project
        ArchivaRepositoryMetadata metadata = readMetadata( dir );
        if ( metadata != null && dir.getName().equals( metadata.getArtifactId() ) )
        {
            return true;
        }

        return false;
    }

    private boolean isProjectVersion( File dir )
    {
        final String artifactId = dir.getParentFile().getName();
        final String projectVersion = dir.getName();

        // check if there is a POM artifact file to ensure it is a version directory
        File[] files;
        if ( VersionUtil.isSnapshot( projectVersion ) )
        {
            files = dir.listFiles( new PomFilenameFilter( artifactId, projectVersion ) );
        }
        else
        {
            final String pomFile = artifactId + "-" + projectVersion + ".pom";
            files = dir.listFiles( new PomFileFilter( pomFile ) );
        }
        if ( files != null && files.length > 0 )
        {
            return true;
        }

        // if a metadata file is present, check if this is the "version" directory, marking it as a project version
        ArchivaRepositoryMetadata metadata = readMetadata( dir );
        if ( metadata != null && projectVersion.equals( metadata.getVersion() ) )
        {
            return true;
        }

        return false;
    }

    private ArchivaRepositoryMetadata readMetadata( File directory )
    {
        ArchivaRepositoryMetadata metadata = null;
        File metadataFile = new File( directory, METADATA_FILENAME );
        if ( metadataFile.exists() )
        {
            try
            {
                metadata = MavenMetadataReader.read( metadataFile );
            }
            catch ( XMLException e )
            {
                // ignore missing or invalid metadata
            }
        }
        return metadata;
    }

    private static class DirectoryFilter
        implements FilenameFilter
    {
        private final Filter<String> filter;

        public DirectoryFilter( Filter<String> filter )
        {
            this.filter = filter;
        }

        @Override
        public boolean accept( File dir, String name )
        {
            if ( !filter.accept( name ) )
            {
                return false;
            }
            else if ( name.startsWith( "." ) )
            {
                return false;
            }
            else if ( !new File( dir, name ).isDirectory() )
            {
                return false;
            }
            return true;
        }
    }

    private static class ArtifactDirectoryFilter
        implements FilenameFilter
    {
        private final Filter<String> filter;

        private ArtifactDirectoryFilter( Filter<String> filter )
        {
            this.filter = filter;
        }

        @Override
        public boolean accept( File dir, String name )
        {
            // TODO compare to logic in maven-repository-layer
            if ( !filter.accept( name ) )
            {
                return false;
            }
            else if ( name.startsWith( "." ) )
            {
                return false;
            }
            else if ( name.endsWith( ".md5" ) || name.endsWith( ".sha1" ) || name.endsWith( ".asc" ) )
            {
                return false;
            }
            else if ( name.equals( METADATA_FILENAME ) )
            {
                return false;
            }
            else if ( new File( dir, name ).isDirectory() )
            {
                return false;
            }
            // some files from remote repositories can have name like maven-metadata-archiva-vm-all-public.xml
            else if ( StringUtils.startsWith( name, METADATA_FILENAME_START ) && StringUtils.endsWith( name, ".xml" ) )
            {
                return false;
            }

            return true;

        }
    }


    private static final class PomFilenameFilter
        implements FilenameFilter
    {

        private final String artifactId, projectVersion;

        private PomFilenameFilter( String artifactId, String projectVersion )
        {
            this.artifactId = artifactId;
            this.projectVersion = projectVersion;
        }

        @Override
        public boolean accept( File dir, String name )
        {
            if ( name.startsWith( artifactId + "-" ) && name.endsWith( ".pom" ) )
            {
                String v = name.substring( artifactId.length() + 1, name.length() - 4 );
                v = VersionUtil.getBaseVersion( v );
                if ( v.equals( projectVersion ) )
                {
                    return true;
                }
            }
            return false;
        }
    }

    private static class PomFileFilter
        implements FilenameFilter
    {
        private final String pomFile;

        private PomFileFilter( String pomFile )
        {
            this.pomFile = pomFile;
        }

        @Override
        public boolean accept( File dir, String name )
        {
            return pomFile.equals( name );
        }
    }


    public PathParser getPathParser()
    {
        return pathParser;
    }

    public void setPathParser( PathParser pathParser )
    {
        this.pathParser = pathParser;
    }
}
