package org.eclipse.aether.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 java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static java.util.Objects.requireNonNull;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * A repository on a remote server.
 */
public final class RemoteRepository
    implements ArtifactRepository
{

    private static final Pattern URL_PATTERN =
        Pattern.compile( "([^:/]+(:[^:/]{2,}+(?=://))?):(//([^@/]*@)?([^/:]+))?.*" );

    private final String id;

    private final String type;

    private final String url;

    private final String host;

    private final String protocol;

    private final RepositoryPolicy releasePolicy;

    private final RepositoryPolicy snapshotPolicy;

    private final Proxy proxy;

    private final Authentication authentication;

    private final List<RemoteRepository> mirroredRepositories;

    private final boolean repositoryManager;

    RemoteRepository( Builder builder )
    {
        if ( builder.prototype != null )
        {
            id = ( builder.delta & Builder.ID ) != 0 ? builder.id : builder.prototype.id;
            type = ( builder.delta & Builder.TYPE ) != 0 ? builder.type : builder.prototype.type;
            url = ( builder.delta & Builder.URL ) != 0 ? builder.url : builder.prototype.url;
            releasePolicy =
                ( builder.delta & Builder.RELEASES ) != 0 ? builder.releasePolicy : builder.prototype.releasePolicy;
            snapshotPolicy =
                ( builder.delta & Builder.SNAPSHOTS ) != 0 ? builder.snapshotPolicy : builder.prototype.snapshotPolicy;
            proxy = ( builder.delta & Builder.PROXY ) != 0 ? builder.proxy : builder.prototype.proxy;
            authentication =
                ( builder.delta & Builder.AUTH ) != 0 ? builder.authentication : builder.prototype.authentication;
            repositoryManager =
                ( builder.delta & Builder.REPOMAN ) != 0 ? builder.repositoryManager
                                : builder.prototype.repositoryManager;
            mirroredRepositories =
                ( builder.delta & Builder.MIRRORED ) != 0 ? copy( builder.mirroredRepositories )
                                : builder.prototype.mirroredRepositories;
        }
        else
        {
            id = builder.id;
            type = builder.type;
            url = builder.url;
            releasePolicy = builder.releasePolicy;
            snapshotPolicy = builder.snapshotPolicy;
            proxy = builder.proxy;
            authentication = builder.authentication;
            repositoryManager = builder.repositoryManager;
            mirroredRepositories = copy( builder.mirroredRepositories );
        }

        Matcher m = URL_PATTERN.matcher( url );
        if ( m.matches() )
        {
            protocol = m.group( 1 );
            String host = m.group( 5 );
            this.host = ( host != null ) ? host : "";
        }
        else
        {
            protocol = host = "";
        }
    }

    private static List<RemoteRepository> copy( List<RemoteRepository> repos )
    {
        if ( repos == null || repos.isEmpty() )
        {
            return Collections.emptyList();
        }
        return Collections.unmodifiableList( Arrays.asList( repos.toArray( new RemoteRepository[repos.size()] ) ) );
    }

    public String getId()
    {
        return id;
    }

    public String getContentType()
    {
        return type;
    }

    /**
     * Gets the (base) URL of this repository.
     * 
     * @return The (base) URL of this repository, never {@code null}.
     */
    public String getUrl()
    {
        return url;
    }

    /**
     * Gets the protocol part from the repository's URL, for example {@code file} or {@code http}. As suggested by RFC
     * 2396, section 3.1 "Scheme Component", the protocol name should be treated case-insensitively.
     * 
     * @return The protocol or an empty string if none, never {@code null}.
     */
    public String getProtocol()
    {
        return protocol;
    }

    /**
     * Gets the host part from the repository's URL.
     * 
     * @return The host or an empty string if none, never {@code null}.
     */
    public String getHost()
    {
        return host;
    }

    /**
     * Gets the policy to apply for snapshot/release artifacts.
     * 
     * @param snapshot {@code true} to retrieve the snapshot policy, {@code false} to retrieve the release policy.
     * @return The requested repository policy, never {@code null}.
     */
    public RepositoryPolicy getPolicy( boolean snapshot )
    {
        return snapshot ? snapshotPolicy : releasePolicy;
    }

    /**
     * Gets the proxy that has been selected for this repository.
     * 
     * @return The selected proxy or {@code null} if none.
     */
    public Proxy getProxy()
    {
        return proxy;
    }

    /**
     * Gets the authentication that has been selected for this repository.
     * 
     * @return The selected authentication or {@code null} if none.
     */
    public Authentication getAuthentication()
    {
        return authentication;
    }

    /**
     * Gets the repositories that this repository serves as a mirror for.
     * 
     * @return The (read-only) repositories being mirrored by this repository, never {@code null}.
     */
    public List<RemoteRepository> getMirroredRepositories()
    {
        return mirroredRepositories;
    }

    /**
     * Indicates whether this repository refers to a repository manager or not.
     * 
     * @return {@code true} if this repository is a repository manager, {@code false} otherwise.
     */
    public boolean isRepositoryManager()
    {
        return repositoryManager;
    }

    @Override
    public String toString()
    {
        StringBuilder buffer = new StringBuilder( 256 );
        buffer.append( getId() );
        buffer.append( " (" ).append( getUrl() );
        buffer.append( ", " ).append( getContentType() );
        boolean r = getPolicy( false ).isEnabled(), s = getPolicy( true ).isEnabled();
        if ( r && s )
        {
            buffer.append( ", releases+snapshots" );
        }
        else if ( r )
        {
            buffer.append( ", releases" );
        }
        else if ( s )
        {
            buffer.append( ", snapshots" );
        }
        else
        {
            buffer.append( ", disabled" );
        }
        if ( isRepositoryManager() )
        {
            buffer.append( ", managed" );
        }
        buffer.append( ")" );
        return buffer.toString();
    }

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

        RemoteRepository that = (RemoteRepository) obj;

        return eq( url, that.url ) && eq( type, that.type ) && eq( id, that.id )
            && eq( releasePolicy, that.releasePolicy ) && eq( snapshotPolicy, that.snapshotPolicy )
            && eq( proxy, that.proxy ) && eq( authentication, that.authentication )
            && eq( mirroredRepositories, that.mirroredRepositories ) && repositoryManager == that.repositoryManager;
    }

    private static <T> boolean eq( T s1, T s2 )
    {
        return s1 != null ? s1.equals( s2 ) : s2 == null;
    }

    @Override
    public int hashCode()
    {
        int hash = 17;
        hash = hash * 31 + hash( url );
        hash = hash * 31 + hash( type );
        hash = hash * 31 + hash( id );
        hash = hash * 31 + hash( releasePolicy );
        hash = hash * 31 + hash( snapshotPolicy );
        hash = hash * 31 + hash( proxy );
        hash = hash * 31 + hash( authentication );
        hash = hash * 31 + hash( mirroredRepositories );
        hash = hash * 31 + ( repositoryManager ? 1 : 0 );
        return hash;
    }

    private static int hash( Object obj )
    {
        return obj != null ? obj.hashCode() : 0;
    }

    /**
     * A builder to create remote repositories.
     */
    public static final class Builder
    {

        private static final RepositoryPolicy DEFAULT_POLICY = new RepositoryPolicy();

        static final int ID = 0x0001, TYPE = 0x0002, URL = 0x0004, RELEASES = 0x0008, SNAPSHOTS = 0x0010,
                        PROXY = 0x0020, AUTH = 0x0040, MIRRORED = 0x0080, REPOMAN = 0x0100;

        int delta;

        RemoteRepository prototype;

        String id;

        String type;

        String url;

        RepositoryPolicy releasePolicy = DEFAULT_POLICY;

        RepositoryPolicy snapshotPolicy = DEFAULT_POLICY;

        Proxy proxy;

        Authentication authentication;

        List<RemoteRepository> mirroredRepositories;

        boolean repositoryManager;

        /**
         * Creates a new repository builder.
         * 
         * @param id The identifier of the repository, may be {@code null}.
         * @param type The type of the repository, may be {@code null}.
         * @param url The (base) URL of the repository, may be {@code null}.
         */
        public Builder( String id, String type, String url )
        {
            this.id = ( id != null ) ? id : "";
            this.type = ( type != null ) ? type : "";
            this.url = ( url != null ) ? url : "";
        }

        /**
         * Creates a new repository builder which uses the specified remote repository as a prototype for the new one.
         * All properties which have not been set on the builder will be copied from the prototype when building the
         * repository.
         *
         * @param prototype The remote repository to use as prototype, must not be {@code null}.
         */
        public Builder( RemoteRepository prototype )
        {
            this.prototype = requireNonNull( prototype, "remote repository prototype cannot be null" );
        }

        /**
         * Builds a new remote repository from the current values of this builder. The state of the builder itself
         * remains unchanged.
         *
         * @return The remote repository, never {@code null}.
         */
        public RemoteRepository build()
        {
            if ( prototype != null && delta == 0 )
            {
                return prototype;
            }
            return new RemoteRepository( this );
        }

        private <T> void delta( int flag, T builder, T prototype )
        {
            boolean equal = ( builder != null ) ? builder.equals( prototype ) : prototype == null;
            if ( equal )
            {
                delta &= ~flag;
            }
            else
            {
                delta |= flag;
            }
        }

        /**
         * Sets the identifier of the repository.
         * 
         * @param id The identifier of the repository, may be {@code null}.
         * @return This builder for chaining, never {@code null}.
         */
        public Builder setId( String id )
        {
            this.id = ( id != null ) ? id : "";
            if ( prototype != null )
            {
                delta( ID, this.id, prototype.getId() );
            }
            return this;
        }

        /**
         * Sets the type of the repository, e.g. "default".
         * 
         * @param type The type of the repository, may be {@code null}.
         * @return This builder for chaining, never {@code null}.
         */
        public Builder setContentType( String type )
        {
            this.type = ( type != null ) ? type : "";
            if ( prototype != null )
            {
                delta( TYPE, this.type, prototype.getContentType() );
            }
            return this;
        }

        /**
         * Sets the (base) URL of the repository.
         * 
         * @param url The URL of the repository, may be {@code null}.
         * @return This builder for chaining, never {@code null}.
         */
        public Builder setUrl( String url )
        {
            this.url = ( url != null ) ? url : "";
            if ( prototype != null )
            {
                delta( URL, this.url, prototype.getUrl() );
            }
            return this;
        }

        /**
         * Sets the policy to apply for snapshot and release artifacts.
         * 
         * @param policy The repository policy to set, may be {@code null} to use a default policy.
         * @return This builder for chaining, never {@code null}.
         */
        public Builder setPolicy( RepositoryPolicy policy )
        {
            this.releasePolicy = this.snapshotPolicy = ( policy != null ) ? policy : DEFAULT_POLICY;
            if ( prototype != null )
            {
                delta( RELEASES, this.releasePolicy, prototype.getPolicy( false ) );
                delta( SNAPSHOTS, this.snapshotPolicy, prototype.getPolicy( true ) );
            }
            return this;
        }

        /**
         * Sets the policy to apply for release artifacts.
         * 
         * @param releasePolicy The repository policy to set, may be {@code null} to use a default policy.
         * @return This builder for chaining, never {@code null}.
         */
        public Builder setReleasePolicy( RepositoryPolicy releasePolicy )
        {
            this.releasePolicy = ( releasePolicy != null ) ? releasePolicy : DEFAULT_POLICY;
            if ( prototype != null )
            {
                delta( RELEASES, this.releasePolicy, prototype.getPolicy( false ) );
            }
            return this;
        }

        /**
         * Sets the policy to apply for snapshot artifacts.
         * 
         * @param snapshotPolicy The repository policy to set, may be {@code null} to use a default policy.
         * @return This builder for chaining, never {@code null}.
         */
        public Builder setSnapshotPolicy( RepositoryPolicy snapshotPolicy )
        {
            this.snapshotPolicy = ( snapshotPolicy != null ) ? snapshotPolicy : DEFAULT_POLICY;
            if ( prototype != null )
            {
                delta( SNAPSHOTS, this.snapshotPolicy, prototype.getPolicy( true ) );
            }
            return this;
        }

        /**
         * Sets the proxy to use in order to access the repository.
         * 
         * @param proxy The proxy to use, may be {@code null}.
         * @return This builder for chaining, never {@code null}.
         */
        public Builder setProxy( Proxy proxy )
        {
            this.proxy = proxy;
            if ( prototype != null )
            {
                delta( PROXY, this.proxy, prototype.getProxy() );
            }
            return this;
        }

        /**
         * Sets the authentication to use in order to access the repository.
         * 
         * @param authentication The authentication to use, may be {@code null}.
         * @return This builder for chaining, never {@code null}.
         */
        public Builder setAuthentication( Authentication authentication )
        {
            this.authentication = authentication;
            if ( prototype != null )
            {
                delta( AUTH, this.authentication, prototype.getAuthentication() );
            }
            return this;
        }

        /**
         * Sets the repositories being mirrored by the repository.
         * 
         * @param mirroredRepositories The repositories being mirrored by the repository, may be {@code null}.
         * @return This builder for chaining, never {@code null}.
         */
        public Builder setMirroredRepositories( List<RemoteRepository> mirroredRepositories )
        {
            if ( this.mirroredRepositories == null )
            {
                this.mirroredRepositories = new ArrayList<RemoteRepository>();
            }
            else
            {
                this.mirroredRepositories.clear();
            }
            if ( mirroredRepositories != null )
            {
                this.mirroredRepositories.addAll( mirroredRepositories );
            }
            if ( prototype != null )
            {
                delta( MIRRORED, this.mirroredRepositories, prototype.getMirroredRepositories() );
            }
            return this;
        }

        /**
         * Adds the specified repository to the list of repositories being mirrored by the repository. If this builder
         * was {@link Builder constructed from a prototype}, the given repository
         * will be added to the list of mirrored repositories from the prototype.
         * 
         * @param mirroredRepository The repository being mirrored by the repository, may be {@code null}.
         * @return This builder for chaining, never {@code null}.
         */
        public Builder addMirroredRepository( RemoteRepository mirroredRepository )
        {
            if ( mirroredRepository != null )
            {
                if ( this.mirroredRepositories == null )
                {
                    this.mirroredRepositories = new ArrayList<RemoteRepository>();
                    if ( prototype != null )
                    {
                        mirroredRepositories.addAll( prototype.getMirroredRepositories() );
                    }
                }
                mirroredRepositories.add( mirroredRepository );
                if ( prototype != null )
                {
                    delta |= MIRRORED;
                }
            }
            return this;
        }

        /**
         * Marks the repository as a repository manager or not.
         * 
         * @param repositoryManager {@code true} if the repository points at a repository manager, {@code false} if the
         *            repository is just serving static contents.
         * @return This builder for chaining, never {@code null}.
         */
        public Builder setRepositoryManager( boolean repositoryManager )
        {
            this.repositoryManager = repositoryManager;
            if ( prototype != null )
            {
                delta( REPOMAN, this.repositoryManager, prototype.isRepositoryManager() );
            }
            return this;
        }

    }

}
