<commit_before>package pokeraidbot.domain;

import me.xdrop.fuzzywuzzy.model.ExtractedResult;
import org.apache.commons.lang3.StringUtils;
import pokeraidbot.domain.errors.GymNotFoundException;
import pokeraidbot.domain.errors.UserMessedUpException;

import java.util.*;
import java.util.stream.Collectors;

import static me.xdrop.fuzzywuzzy.FuzzySearch.extractTop;
import static org.apache.commons.lang3.StringUtils.containsIgnoreCase;

public class GymRepository {
    private Map<String, Set<Gym>> gymsPerRegion = new HashMap<>();
    private final LocaleService localeService;

    public GymRepository(Map<String, Set<Gym>> gyms, LocaleService localeService) {
        this.localeService = localeService;
        for (String region : gyms.keySet()) {
            Set<Gym> gymsForRegion = gyms.get(region);
            this.gymsPerRegion.put(region, gymsForRegion);
        }
    }

    public Gym search(String userName, String query, String region) {
        if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(query)) {
            throw new UserMessedUpException(userName, localeService.getMessageFor(LocaleService.GYM_SEARCH,
                    LocaleService.DEFAULT));
        }

        final Set<Gym> gyms = getAllGymsForRegion(region);

        final Locale localeForUser = localeService.getLocaleForUser(userName);
        final Optional<Gym> gym = get(query, region);
        if (gym.isPresent()) {
            return gym.get();
        } else {
            //70 seems like a reasonable cutoff here...
            List<ExtractedResult> candidates = extractTop(query, gyms.stream().map(s -> s.getName()).collect(Collectors.toList()), 6, 70);
            if (candidates.size() == 1) {
                return findByName(candidates.iterator().next().getString(), region);
            } else if (candidates.size() < 1) {
                throw new GymNotFoundException(query, localeService, LocaleService.SWEDISH);
            } else {
                List<Gym> matchingPartial = getMatchingPartial(query, region, candidates);
                if (matchingPartial.size() == 1) {
                    return matchingPartial.get(0);
                }
                if (candidates.size() <= 5) {
                    String possibleMatches = candidates.stream().map(s -> findByName(s.getString(), region).getName()).collect(Collectors.joining(", "));
                    throw new UserMessedUpException(userName,
                            localeService.getMessageFor(LocaleService.GYM_SEARCH_OPTIONS, localeForUser, possibleMatches));
                } else {
                    throw new UserMessedUpException(userName, localeService.getMessageFor(LocaleService.GYM_SEARCH_MANY_RESULTS, localeForUser));
                }
            }
        }
    }

    public Gym findByName(String name, String region) {
        final Optional<Gym> gym = get(name, region);
        if (!gym.isPresent()) {
            throw new GymNotFoundException(name, localeService, LocaleService.SWEDISH);
        }
        return gym.get();
    }

    public Gym findById(String id, String region) {
        for (Gym gym : getAllGymsForRegion(region)) {
            if (gym.getId().equals(id))
                return gym;
        }
        throw new GymNotFoundException("[No entry]", localeService, LocaleService.SWEDISH);
    }

    public Set<Gym> getAllGymsForRegion(String region) {
        final Set<Gym> gyms = gymsPerRegion.get(region);
        if (gyms == null || gyms.size() < 1) {
            throw new RuntimeException(localeService.getMessageFor(LocaleService.GYM_CONFIG_ERROR, LocaleService.DEFAULT));
        }
        return gyms;
    }

    private Optional<Gym> get(String name, String region) {
        return getAllGymsForRegion(region).stream().filter(s -> s.getName().equalsIgnoreCase(name)).findFirst();
    }

    private List<Gym> getMatchingPartial(String query, String region, List<ExtractedResult> candidates) {
        List<Gym> mathingGyms = new ArrayList<>();
        for (ExtractedResult result : candidates) {
            if (containsIgnoreCase(result.getString(), query)) {
                mathingGyms.add(findByName(result.getString(), region));
            }
        }
        return mathingGyms;
    }
}<commit_msg>Clean up query for exact partial match<commit_after>package pokeraidbot.domain;

import me.xdrop.fuzzywuzzy.model.ExtractedResult;
import org.apache.commons.lang3.StringUtils;
import pokeraidbot.domain.errors.GymNotFoundException;
import pokeraidbot.domain.errors.UserMessedUpException;

import java.util.*;
import java.util.stream.Collectors;

import static me.xdrop.fuzzywuzzy.FuzzySearch.extractTop;
import static org.apache.commons.lang3.StringUtils.containsIgnoreCase;

public class GymRepository {
    private Map<String, Set<Gym>> gymsPerRegion = new HashMap<>();
    private final LocaleService localeService;

    public GymRepository(Map<String, Set<Gym>> gyms, LocaleService localeService) {
        this.localeService = localeService;
        for (String region : gyms.keySet()) {
            Set<Gym> gymsForRegion = gyms.get(region);
            this.gymsPerRegion.put(region, gymsForRegion);
        }
    }

    public Gym search(String userName, String query, String region) {
        if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(query)) {
            throw new UserMessedUpException(userName, localeService.getMessageFor(LocaleService.GYM_SEARCH,
                    LocaleService.DEFAULT));
        }

        final Set<Gym> gyms = getAllGymsForRegion(region);

        final Locale localeForUser = localeService.getLocaleForUser(userName);
        final Optional<Gym> gym = get(query, region);
        if (gym.isPresent()) {
            return gym.get();
        } else {
            //70 seems like a reasonable cutoff here...
            List<ExtractedResult> candidates = extractTop(query, gyms.stream().map(s -> s.getName()).collect(Collectors.toList()), 6, 70);
            if (candidates.size() == 1) {
                return findByName(candidates.iterator().next().getString(), region);
            } else if (candidates.size() < 1) {
                throw new GymNotFoundException(query, localeService, LocaleService.SWEDISH);
            } else {
                List<Gym> matchingPartial = getMatchingPartial(query, region, candidates);
                if (matchingPartial.size() == 1) {
                    return matchingPartial.get(0);
                }
                if (candidates.size() <= 5) {
                    String possibleMatches = candidates.stream().map(s -> findByName(s.getString(), region).getName()).collect(Collectors.joining(", "));
                    throw new UserMessedUpException(userName,
                            localeService.getMessageFor(LocaleService.GYM_SEARCH_OPTIONS, localeForUser, possibleMatches));
                } else {
                    throw new UserMessedUpException(userName, localeService.getMessageFor(LocaleService.GYM_SEARCH_MANY_RESULTS, localeForUser));
                }
            }
        }
    }

    public Gym findByName(String name, String region) {
        final Optional<Gym> gym = get(name, region);
        if (!gym.isPresent()) {
            throw new GymNotFoundException(name, localeService, LocaleService.SWEDISH);
        }
        return gym.get();
    }

    public Gym findById(String id, String region) {
        for (Gym gym : getAllGymsForRegion(region)) {
            if (gym.getId().equals(id))
                return gym;
        }
        throw new GymNotFoundException("[No entry]", localeService, LocaleService.SWEDISH);
    }

    public Set<Gym> getAllGymsForRegion(String region) {
        final Set<Gym> gyms = gymsPerRegion.get(region);
        if (gyms == null || gyms.size() < 1) {
            throw new RuntimeException(localeService.getMessageFor(LocaleService.GYM_CONFIG_ERROR, LocaleService.DEFAULT));
        }
        return gyms;
    }

    private Optional<Gym> get(String name, String region) {
        return getAllGymsForRegion(region).stream().filter(s -> s.getName().equalsIgnoreCase(name)).findFirst();
    }

    private List<Gym> getMatchingPartial(String query, String region, List<ExtractedResult> candidates) {
        String cleanQuery = query.trim().replaceAll(" +", " ");
        List<Gym> mathingGyms = new ArrayList<>();
        for (ExtractedResult result : candidates) {
            if (containsIgnoreCase(result.getString(), cleanQuery)) {
                mathingGyms.add(findByName(result.getString(), region));
            }
        }
        return mathingGyms;
    }
}
{'fraction_non_alphanumeric': 0.10976462363085528, 'fraction_numerical': 0.0030295968305756233, 'mean_word_length': 2.6585677749360612, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '4327385', 'n_tokens_mistral': 2433, 'n_tokens_neox': 2339, 'n_words': 479}