<commit_before>/**
 *  Copyright 2005-2014 Red Hat, Inc.
 *
 *  Red Hat 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.
 */
package io.fabric8.api;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import org.jboss.gravia.utils.IllegalArgumentAssertion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.MapDifference;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.collect.Sets.SetView;

/**
 * Helper methods for working with profiles
 */
public final class Profiles {

    private static final Logger LOGGER = LoggerFactory.getLogger(Profiles.class);
    
    // Hide ctor
    private Profiles() {
    }
    
    /**
     * Should we convert a directory of profiles called "foo-bar" into a directory "foo/bar.profile" structure to use
     * the file system better, to better organise profiles into folders and make it easier to work with profiles in the wiki
     */
    public static final boolean useDirectoriesForProfiles = true;
    public static final String PROFILE_FOLDER_SUFFIX = ".profile";

    public static List<String> profileIds(Iterable<Profile> profiles) {
        List<String> answer = new ArrayList<String>();
        if (profiles != null) {
            for (Profile profile : profiles) {
                answer.add(profile.getId());
            }
        }
        return answer;
    }

    public static List<String> profileIds(Profile... profiles) {
        List<String> answer = new ArrayList<String>();
        if (profiles != null) {
            for (Profile profile : profiles) {
                answer.add(profile.getId());
            }
        }
        return answer;
    }


    public static String versionId(Version version) {
        return version != null ? version.getId() : null;
    }

    public static List<String> versionIds(Version... versions) {
        List<String> answer = new ArrayList<String>();
        if (versions != null) {
            for (Version version : versions) {
                answer.add(version.getId());
            }
        }
        return answer;
    }

    public static List<String> versionIds(Iterable<Version> versions) {
        List<String> answer = new ArrayList<String>();
        if (versions != null) {
            for (Version version : versions) {
                answer.add(version.getId());
            }
        }
        return answer;
    }


    /**
     * Returns the profile for the given id if it exists in the array or null
     */
    public static Profile profile(Profile[] profiles, String profileId) {
        if (profiles != null) {
            for (Profile profile : profiles) {
                if (profileId.equals(profile.getId())) {
                    return profile;
                }
            }
        }
        return null;
    }

    /**
     * Returns the configuration file names for the given profile
     */
    public static Set<String> getConfigurationFileNames(Collection<Profile> profiles) {
        Set<String> set = new HashSet<String>();
        for (Profile profile : profiles) {
            set.addAll(profile.getConfigurationFileNames());
        }
        return set;
    }

    /**
     * Returns the configuration file data for the given file name and list of inherited profiles
     */
    public static byte[] getFileConfiguration(Collection<Profile> profiles, String fileName) {
        byte[] answer = null;
        for (Profile profile : profiles) {
            answer = profile.getFileConfiguration(fileName);
            if (answer != null) {
                break;
            }
        }
        return answer;
    }


    /**
     * Returns the configuration file names for the given profile
     */
    public static Map<String,String> getConfigurationFileNameMap(Profile[] profiles) {
        Map<String, String> answer = new TreeMap<String, String>();
        for (Profile profile : profiles) {
            String id = profile.getId();
            Set<String> files = profile.getConfigurationFileNames();
            for (String file : files) {
                if (!answer.containsKey(file)) {
                    answer.put(file, id);
                }
            }
        }
        return answer;
    }

    /**
     * Get the effective profile, which is the overlay profile with substituted configurations.
     */
    public static Profile getEffectiveProfile(FabricService fabricService, Profile profile) {
        ProfileService profileService = fabricService.adapt(ProfileService.class);
        Profile overlayProfile = profileService.getOverlayProfile(profile);
        Map<String, Map<String, String>> configurations = overlayProfile.getConfigurations();
        ProfileBuilder builder = ProfileBuilder.Factory.createFrom(overlayProfile);
        builder.setConfigurations(fabricService.substituteConfigurations(configurations));
        return builder.getProfile();
    }
    
    /**
     * Returns the overlay configuration for the given list of profile ids and the configuration PID.
     *
     * This method will find the overlay profile for each profile id and combine all the configurations together.
     *
     * Usually we would use the Profile objects directly; but this API call is useful when creating new containers; letting us
     * figure out the effective overlay before a container exists.
     */
    public static Map<String, String> getOverlayConfiguration(FabricService fabricService, Iterable<String> profileIds, String versionId, String pid) {
        ProfileService profileService = fabricService.adapt(ProfileService.class);
        Map<String, String> overlayConfig = new HashMap<String, String>();
        Version version = null;
        if (versionId == null) {
            version = fabricService.getRequiredDefaultVersion();
        } else {
            version = profileService.getRequiredVersion(versionId);
        }
        if (profileIds != null) {
            for (String profileId : profileIds) {
                Profile profile = version.getRequiredProfile(profileId);
                Profile overlay = profileService.getOverlayProfile(profile);
                Map<String, String> profileConfig = overlay.getConfiguration(pid);
                if (profileConfig != null) {
                    overlayConfig.putAll(profileConfig);
                }
            }
        }
        return overlayConfig;
    }

    /**
     * Returns the overlay factory configurations for the given list of profile ids which start with the given pid. (e.g. of the form "$pid-foo.properties"
     *
     * This method will find the overlay profile for each profile id and combine all the configurations together.
     *
     * Usually we would use the Profile objects directly; but this API call is useful when creating new containers; letting us
     * figure out the effective overlay before a container exists.
     */
    public static Map<String, Map<String, String>> getOverlayFactoryConfigurations(FabricService fabricService, Iterable<String> profileIds, String versionId, String pid) {
        ProfileService profileService = fabricService.adapt(ProfileService.class);<commit_msg>avoid failing test cases (which may not have a ProfileService as the FabricService may be a mock<commit_after>/**
 *  Copyright 2005-2014 Red Hat, Inc.
 *
 *  Red Hat 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.
 */
package io.fabric8.api;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import org.jboss.gravia.utils.IllegalArgumentAssertion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.MapDifference;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.collect.Sets.SetView;

/**
 * Helper methods for working with profiles
 */
public final class Profiles {

    private static final Logger LOGGER = LoggerFactory.getLogger(Profiles.class);
    
    // Hide ctor
    private Profiles() {
    }
    
    /**
     * Should we convert a directory of profiles called "foo-bar" into a directory "foo/bar.profile" structure to use
     * the file system better, to better organise profiles into folders and make it easier to work with profiles in the wiki
     */
    public static final boolean useDirectoriesForProfiles = true;
    public static final String PROFILE_FOLDER_SUFFIX = ".profile";

    public static List<String> profileIds(Iterable<Profile> profiles) {
        List<String> answer = new ArrayList<String>();
        if (profiles != null) {
            for (Profile profile : profiles) {
                answer.add(profile.getId());
            }
        }
        return answer;
    }

    public static List<String> profileIds(Profile... profiles) {
        List<String> answer = new ArrayList<String>();
        if (profiles != null) {
            for (Profile profile : profiles) {
                answer.add(profile.getId());
            }
        }
        return answer;
    }


    public static String versionId(Version version) {
        return version != null ? version.getId() : null;
    }

    public static List<String> versionIds(Version... versions) {
        List<String> answer = new ArrayList<String>();
        if (versions != null) {
            for (Version version : versions) {
                answer.add(version.getId());
            }
        }
        return answer;
    }

    public static List<String> versionIds(Iterable<Version> versions) {
        List<String> answer = new ArrayList<String>();
        if (versions != null) {
            for (Version version : versions) {
                answer.add(version.getId());
            }
        }
        return answer;
    }


    /**
     * Returns the profile for the given id if it exists in the array or null
     */
    public static Profile profile(Profile[] profiles, String profileId) {
        if (profiles != null) {
            for (Profile profile : profiles) {
                if (profileId.equals(profile.getId())) {
                    return profile;
                }
            }
        }
        return null;
    }

    /**
     * Returns the configuration file names for the given profile
     */
    public static Set<String> getConfigurationFileNames(Collection<Profile> profiles) {
        Set<String> set = new HashSet<String>();
        for (Profile profile : profiles) {
            set.addAll(profile.getConfigurationFileNames());
        }
        return set;
    }

    /**
     * Returns the configuration file data for the given file name and list of inherited profiles
     */
    public static byte[] getFileConfiguration(Collection<Profile> profiles, String fileName) {
        byte[] answer = null;
        for (Profile profile : profiles) {
            answer = profile.getFileConfiguration(fileName);
            if (answer != null) {
                break;
            }
        }
        return answer;
    }


    /**
     * Returns the configuration file names for the given profile
     */
    public static Map<String,String> getConfigurationFileNameMap(Profile[] profiles) {
        Map<String, String> answer = new TreeMap<String, String>();
        for (Profile profile : profiles) {
            String id = profile.getId();
            Set<String> files = profile.getConfigurationFileNames();
            for (String file : files) {
                if (!answer.containsKey(file)) {
                    answer.put(file, id);
                }
            }
        }
        return answer;
    }

    /**
     * Get the effective profile, which is the overlay profile with substituted configurations.
     */
    public static Profile getEffectiveProfile(FabricService fabricService, Profile profile) {
        ProfileService profileService = fabricService.adapt(ProfileService.class);
        Profile overlayProfile = profileService.getOverlayProfile(profile);
        Map<String, Map<String, String>> configurations = overlayProfile.getConfigurations();
        ProfileBuilder builder = ProfileBuilder.Factory.createFrom(overlayProfile);
        builder.setConfigurations(fabricService.substituteConfigurations(configurations));
        return builder.getProfile();
    }
    
    /**
     * Returns the overlay configuration for the given list of profile ids and the configuration PID.
     *
     * This method will find the overlay profile for each profile id and combine all the configurations together.
     *
     * Usually we would use the Profile objects directly; but this API call is useful when creating new containers; letting us
     * figure out the effective overlay before a container exists.
     */
    public static Map<String, String> getOverlayConfiguration(FabricService fabricService, Iterable<String> profileIds, String versionId, String pid) {
        Map<String, String> overlayConfig = new HashMap<String, String>();
        ProfileService profileService = fabricService.adapt(ProfileService.class);
        // this should only be null in test cases
        if (profileService != null) {
            Version version = null;
            if (versionId == null) {
                version = fabricService.getRequiredDefaultVersion();
            } else {
                version = profileService.getRequiredVersion(versionId);
            }
            if (profileIds != null) {
                for (String profileId : profileIds) {
                    Profile profile = version.getRequiredProfile(profileId);
                    Profile overlay = profileService.getOverlayProfile(profile);
                    Map<String, String> profileConfig = overlay.getConfiguration(pid);
                    if (profileConfig != null) {
                        overlayConfig.putAll(profileConfig);
                    }
                }
            }
        }
        return overlayConfig;
    }

    /**
     * Returns the overlay factory configurations for the given list of profile ids which start with the given pid. (e.g. of the form "$pid-foo.properties"
     *
     * This method will find the overlay profile for each profile id and combine all the configurations together.
     *
     * Usually we would use the Profile objects directly; but this API call is useful when creating new containers; letting us
     * figure out the effective overlay before a container exists.
     */
    public static Map<String, Map<String, String>> getOverlayFactoryConfigurations(FabricService fabricService, Iterable<String> profileIds, String versionId, String pid) {
        ProfileService profileService = fabricService.adapt(ProfileService.class);
{'fraction_non_alphanumeric': 0.08533184606804238, 'fraction_numerical': 0.0018590816136828407, 'mean_word_length': 2.481018119068162, 'pattern_counts': {'":': 0, '<': 69, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2367686', 'n_tokens_mistral': 4014, 'n_tokens_neox': 3912, 'n_words': 1344}