package org.apache.maven.surefire.providerapi;

/*
 * 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 javax.annotation.Nonnull;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;

import static java.lang.Character.isJavaIdentifierPart;
import static java.lang.Character.isJavaIdentifierStart;
import static java.util.Collections.emptySet;
import static org.apache.maven.surefire.util.ReflectionUtils.getConstructor;

/**
 * SPI loader for Surefire/Failsafe should use {@link Thread#getContextClassLoader() current ClassLoader}.
 * <br>
 * The {@link java.util.ServiceLoader} embedded in JVM uses
 * {@link ClassLoader#getSystemClassLoader() System ClassLoader} and cannot be used in Surefire/Failsafe.
 *
 * @since 2.20
 */
public final class ServiceLoader
{

    @Nonnull
    @SuppressWarnings( "unchecked" )
    public <T> Set<T> load( Class<T> clazz, ClassLoader classLoader )
    {
        try
        {
            Set<T> implementations = new HashSet<>();
            for ( String fullyQualifiedClassName : lookup( clazz, classLoader ) )
            {
                Class<?> implClass = classLoader.loadClass( fullyQualifiedClassName );
                implementations.add( (T) getConstructor( implClass ).newInstance() );
            }
            return implementations;
        }
        catch ( IOException | ReflectiveOperationException e )
        {
            throw new IllegalStateException( e.getLocalizedMessage(), e );
        }
    }

    @Nonnull
    public Set<String> lookup( Class<?> clazz, ClassLoader classLoader )
            throws IOException
    {
        final String resourceName = "META-INF/services/" + clazz.getName();

        if ( classLoader == null )
        {
            return emptySet();
        }
        final Enumeration<URL> urls = classLoader.getResources( resourceName );
        return lookupSpiImplementations( urls );
    }

    /**
     * Method loadServices loads the services of a class that are
     * defined using the SPI mechanism.
     *
     * @param urlEnumeration The urls from the resource
     * @return The set of service provider names
     * @throws IOException When reading the streams fails
     */
    @Nonnull
    @SuppressWarnings( "checkstyle:innerassignment" )
    private static Set<String> lookupSpiImplementations( final Enumeration<URL> urlEnumeration )
            throws IOException
    {
        final Set<String> names = new HashSet<>();
        nextUrl:
        while ( urlEnumeration.hasMoreElements() )
        {
            final URL url = urlEnumeration.nextElement();
            try ( BufferedReader reader = getReader( url ) )
            {
                for ( String line; ( line = reader.readLine() ) != null; )
                {
                    int ci = line.indexOf( '#' );
                    if ( ci >= 0 )
                    {
                        line = line.substring( 0, ci );
                    }
                    line = line.trim();
                    int n = line.length();
                    if ( n == 0 )
                    {
                        continue; // next line
                    }

                    if ( line.indexOf( ' ' ) >= 0 || line.indexOf( '\t' ) >= 0 )
                    {
                        continue nextUrl; // next url
                    }
                    char cp = line.charAt( 0 ); // should use codePointAt but this was JDK1.3
                    if ( !isJavaIdentifierStart( cp ) )
                    {
                        continue nextUrl; // next url
                    }
                    for ( int i = 1; i < n; i++ )
                    {
                        cp = line.charAt( i );  // should use codePointAt but this was JDK1.3
                        if ( !isJavaIdentifierPart( cp ) && cp != '.' )
                        {
                            continue nextUrl; // next url
                        }
                    }
                    if ( !names.contains( line ) )
                    {
                        names.add( line );
                    }
                }
            }
        }

        return names;
    }

    @Nonnull
    private static BufferedReader getReader( @Nonnull URL url )
            throws IOException
    {
        final InputStream inputStream = url.openStream();
        final InputStreamReader inputStreamReader = new InputStreamReader( inputStream );
        return new BufferedReader( inputStreamReader );
    }
}
