// Path: src/main/java/de/skuzzle/enforcer/restrictimports/util/Preconditions.java
// public final class Preconditions {
// 
//     public static void checkArgument(boolean condition) {
//         checkArgument(condition, "Unexpected argument");
//     }
// 
//     public static void checkArgument(boolean condition, String message, Object... args) {
//         if (!condition) {
//             throw new IllegalArgumentException(String.format(message, args));
//         }
//     }
// 
//     public static void checkState(boolean condition) {
//         checkState(condition, "Unexpected state");
//     }
// 
//     public static void checkState(boolean condition, String message, Object... args) {
//         if (!condition) {
//             throw new IllegalStateException(String.format(message, args));
//         }
//     }
// 
//     private Preconditions() {
//         throw new IllegalStateException("hidden");
//     }
// }


import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.ServiceLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.skuzzle.enforcer.restrictimports.util.Preconditions;
package de.skuzzle.enforcer.restrictimports.parser.lang;




/**
 * Helper class to list available {@link LanguageSupport} implementations from
 * {@link ServiceLoader}.
 */
final class SupportedLanguageHolder {

    private static final Logger logger = LoggerFactory.getLogger(SupportedLanguageHolder.class);

    // maps from normalized extension to LanguageSupport instance
    // normalized extensions are all lower case and have a leading '.'
    static final Map<String, LanguageSupport> supportedLanguages = lookupImplementations();

    static Optional<LanguageSupport> getLanguageSupport(String extension) {
        final String normalizedExtension = determineNormalizedExtension(extension);
        return Optional.ofNullable(supportedLanguages.get(normalizedExtension));
    }

    static boolean isLanguageSupported(String extension) {
        final String normalizedExtension = determineNormalizedExtension(extension);
        return supportedLanguages.containsKey(normalizedExtension);
    }

    /**
     * Looks up the available {@link LanguageSupport} implementations that can be found
     * using Java's {@link ServiceLoader}
     *
     * @return The implementations, mapped by their supported extensions.
     */
    private static Map<String, LanguageSupport> lookupImplementations() {
        final ServiceLoader<LanguageSupport> serviceProvider = ServiceLoader.load(LanguageSupport.class);
        final Map<String, LanguageSupport> implementations = new HashMap<>();
        serviceProvider.forEach(parser -> parser.getSupportedFileExtensions().stream()
                .map(SupportedLanguageHolder::determineNormalizedExtension)
                .forEach(normalizedExtension -> {

                    if (implementations.put(normalizedExtension, parser) != null) {
                        throw new IllegalStateException(
                                "There are multiple parsers to handle file extension: " + normalizedExtension);
                    }
                    logger.debug("Registered {} for extension '{}'", parser, normalizedExtension);
                }));
// Path: src/main/java/de/skuzzle/enforcer/restrictimports/util/Preconditions.java
// public final class Preconditions {
// 
//     public static void checkArgument(boolean condition) {
//         checkArgument(condition, "Unexpected argument");
//     }
// 
//     public static void checkArgument(boolean condition, String message, Object... args) {
//         if (!condition) {
//             throw new IllegalArgumentException(String.format(message, args));
//         }
//     }
// 
//     public static void checkState(boolean condition) {
//         checkState(condition, "Unexpected state");
//     }
// 
//     public static void checkState(boolean condition, String message, Object... args) {
//         if (!condition) {
//             throw new IllegalStateException(String.format(message, args));
//         }
//     }
// 
//     private Preconditions() {
//         throw new IllegalStateException("hidden");
//     }
// }


// Path: src/main/java/de/skuzzle/enforcer/restrictimports/parser/lang/SupportedLanguageHolder.java
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.ServiceLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.skuzzle.enforcer.restrictimports.util.Preconditions;

package de.skuzzle.enforcer.restrictimports.parser.lang;




/**
 * Helper class to list available {@link LanguageSupport} implementations from
 * {@link ServiceLoader}.
 */
final class SupportedLanguageHolder {

    private static final Logger logger = LoggerFactory.getLogger(SupportedLanguageHolder.class);

    // maps from normalized extension to LanguageSupport instance
    // normalized extensions are all lower case and have a leading '.'
    static final Map<String, LanguageSupport> supportedLanguages = lookupImplementations();

    static Optional<LanguageSupport> getLanguageSupport(String extension) {
        final String normalizedExtension = determineNormalizedExtension(extension);
        return Optional.ofNullable(supportedLanguages.get(normalizedExtension));
    }

    static boolean isLanguageSupported(String extension) {
        final String normalizedExtension = determineNormalizedExtension(extension);
        return supportedLanguages.containsKey(normalizedExtension);
    }

    /**
     * Looks up the available {@link LanguageSupport} implementations that can be found
     * using Java's {@link ServiceLoader}
     *
     * @return The implementations, mapped by their supported extensions.
     */
    private static Map<String, LanguageSupport> lookupImplementations() {
        final ServiceLoader<LanguageSupport> serviceProvider = ServiceLoader.load(LanguageSupport.class);
        final Map<String, LanguageSupport> implementations = new HashMap<>();
        serviceProvider.forEach(parser -> parser.getSupportedFileExtensions().stream()
                .map(SupportedLanguageHolder::determineNormalizedExtension)
                .forEach(normalizedExtension -> {

                    if (implementations.put(normalizedExtension, parser) != null) {
                        throw new IllegalStateException(
                                "There are multiple parsers to handle file extension: " + normalizedExtension);
                    }
                    logger.debug("Registered {} for extension '{}'", parser, normalizedExtension);
                }));
        Preconditions.checkState(!implementations.isEmpty(), "No LanguageSupport instances found!");