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.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.eclipse.aether.RepositorySystemSession;

/**
 * A helper to calculate a fingerprint/digest for the authentication data of a repository/proxy. Such a fingerprint can
 * be used to detect changes in the authentication data across JVM restarts without exposing sensitive information.
 */
public final class AuthenticationDigest
{

    private final MessageDigest digest;

    private final RepositorySystemSession session;

    private final RemoteRepository repository;

    private final Proxy proxy;

    /**
     * Gets the fingerprint for the authentication of the specified repository.
     * 
     * @param session The repository system session during which the fingerprint is requested, must not be {@code null}.
     * @param repository The repository whose authentication is to be fingerprinted, must not be {@code null}.
     * @return The fingerprint of the repository authentication or an empty string if no authentication is configured,
     *         never {@code null}.
     */
    public static String forRepository( RepositorySystemSession session, RemoteRepository repository )
    {
        String digest = "";
        Authentication auth = repository.getAuthentication();
        if ( auth != null )
        {
            AuthenticationDigest authDigest = new AuthenticationDigest( session, repository, null );
            auth.digest( authDigest );
            digest = authDigest.digest();
        }
        return digest;
    }

    /**
     * Gets the fingerprint for the authentication of the specified repository's proxy.
     * 
     * @param session The repository system session during which the fingerprint is requested, must not be {@code null}.
     * @param repository The repository whose proxy authentication is to be fingerprinted, must not be {@code null}.
     * @return The fingerprint of the proxy authentication or an empty string if no proxy is present or if no proxy
     *         authentication is configured, never {@code null}.
     */
    public static String forProxy( RepositorySystemSession session, RemoteRepository repository )
    {
        String digest = "";
        Proxy proxy = repository.getProxy();
        if ( proxy != null )
        {
            Authentication auth = proxy.getAuthentication();
            if ( auth != null )
            {
                AuthenticationDigest authDigest = new AuthenticationDigest( session, repository, proxy );
                auth.digest( authDigest );
                digest = authDigest.digest();
            }
        }
        return digest;
    }

    private AuthenticationDigest( RepositorySystemSession session, RemoteRepository repository, Proxy proxy )
    {
        this.session = session;
        this.repository = repository;
        this.proxy = proxy;
        digest = newDigest();
    }

    private static MessageDigest newDigest()
    {
        try
        {
            return MessageDigest.getInstance( "SHA-1" );
        }
        catch ( NoSuchAlgorithmException e )
        {
            try
            {
                return MessageDigest.getInstance( "MD5" );
            }
            catch ( NoSuchAlgorithmException ne )
            {
                throw new IllegalStateException( ne );
            }
        }
    }

    /**
     * Gets the repository system session during which the authentication fingerprint is calculated.
     * 
     * @return The repository system session, never {@code null}.
     */
    public RepositorySystemSession getSession()
    {
        return session;
    }

    /**
     * Gets the repository requiring authentication. If {@link #getProxy()} is not {@code null}, the data gathered by
     * this authentication digest does not apply to the repository's host but rather the proxy.
     * 
     * @return The repository to be contacted, never {@code null}.
     */
    public RemoteRepository getRepository()
    {
        return repository;
    }

    /**
     * Gets the proxy (if any) to be authenticated with.
     * 
     * @return The proxy or {@code null} if authenticating directly with the repository's host.
     */
    public Proxy getProxy()
    {
        return proxy;
    }

    /**
     * Updates the digest with the specified strings.
     * 
     * @param strings The strings to update the digest with, may be {@code null} or contain {@code null} elements.
     */
    public void update( String... strings )
    {
        if ( strings != null )
        {
            for ( String string : strings )
            {
                if ( string != null )
                {
                    digest.update( string.getBytes( StandardCharsets.UTF_8 ) );
                }
            }
        }
    }

    /**
     * Updates the digest with the specified characters.
     * 
     * @param chars The characters to update the digest with, may be {@code null}.
     */
    @SuppressWarnings( "checkstyle:magicnumber" )
    public void update( char... chars )
    {
        if ( chars != null )
        {
            for ( char c : chars )
            {
                digest.update( (byte) ( c >> 8 ) );
                digest.update( (byte) ( c & 0xFF ) );
            }
        }
    }

    /**
     * Updates the digest with the specified bytes.
     * 
     * @param bytes The bytes to update the digest with, may be {@code null}.
     */
    public void update( byte... bytes )
    {
        if ( bytes != null )
        {
            digest.update( bytes );
        }
    }

    @SuppressWarnings( "checkstyle:magicnumber" )
    private String digest()
    {
        byte[] bytes = digest.digest();
        StringBuilder buffer = new StringBuilder( bytes.length * 2 );
        for ( byte aByte : bytes )
        {
            int b = aByte & 0xFF;
            if ( b < 0x10 )
            {
                buffer.append( '0' );
            }
            buffer.append( Integer.toHexString( b ) );
        }
        return buffer.toString();
    }

}
