package launcher.hasher;
import launcher.LauncherAPI;
import launcher.helper.IOHelper;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.regex.Pattern;
public final class FileNameMatcher
{
private static final Entry[] NO_ENTRIES = new Entry[0];
// Instance
private final Entry[] update;
private final Entry[] verify;
private final Entry[] exclusions;
@LauncherAPI
public FileNameMatcher(String[] update, String[] verify, String[] exclusions)
{
this.update = toEntries(update);
this.verify = toEntries(verify);
this.exclusions = toEntries(exclusions);
}
private FileNameMatcher(Entry[] update, Entry[] verify, Entry[] exclusions)
{
this.update = update;
this.verify = verify;
this.exclusions = exclusions;
}
private static boolean anyMatch(Entry[] entries, Collection<String> path)
{
return Arrays.stream(entries).anyMatch(e -> e.matches(path));
}
private static Entry[] toEntries(String... entries)
{
return Arrays.stream(entries).map(Entry::new).toArray(Entry[]::new);
}
@LauncherAPI
public boolean shouldUpdate(Collection<String> path)
{
return (anyMatch(update, path) || anyMatch(verify, path)) && !anyMatch(exclusions, path);
}
@LauncherAPI
public boolean shouldVerify(Collection<String> path)
{
return anyMatch(verify, path) && !anyMatch(exclusions, path);
}
@LauncherAPI
public FileNameMatcher verifyOnly()
{
return new FileNameMatcher(NO_ENTRIES, verify, exclusions);
}
private static final class Entry
{
private static final Pattern SPLITTER = Pattern.compile(Pattern.quote(IOHelper.CROSS_SEPARATOR) + '+');
private final Pattern[] parts;
private Entry(CharSequence exclusion)
{
parts = SPLITTER.splitAsStream(exclusion).map(Pattern::compile).toArray(Pattern[]::new);
}
private boolean matches(Collection<String> path)
{
if (parts.length > path.size())
{
return false;
}
// Verify path parts
Iterator<String> iterator = path.iterator();
for (Pattern patternPart : parts)
{
String pathPart = iterator.next();
if (!patternPart.matcher(pathPart).matches())
{
return false;
}
}
// All matches
return true;
}
}
}