package com.loopperfect.buckaroo;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Stream;
public final class DependencyGroup {
public final ImmutableMap<RecipeIdentifier, SemanticVersionRequirement> dependencies;
private DependencyGroup(final ImmutableMap<RecipeIdentifier, SemanticVersionRequirement> dependencies) {
this.dependencies = Preconditions.checkNotNull(dependencies);
}
public boolean isEmpty() {
return dependencies.isEmpty();
}
public boolean requires(final RecipeIdentifier identifier) {
Preconditions.checkNotNull(identifier);
return dependencies.containsKey(identifier);
}
public ImmutableList<Dependency> entries() {
return dependencies.entrySet()
.stream()
.map(x -> Dependency.of(x.getKey(), x.getValue()))
.collect(ImmutableList.toImmutableList());
}
public DependencyGroup addDependency(final Dependency dependency) {
Preconditions.checkNotNull(dependency);
if (dependencies.containsKey(dependency.project) &&
dependencies.get(dependency.project).equals(dependency.versionRequirement)) {
return this;
}
return new DependencyGroup(
Stream.concat(
dependencies.entrySet()
.stream()
.filter(x -> !x.getKey().equals(dependency.project)),
Stream.of(Maps.immutableEntry(dependency.project, dependency.versionRequirement)))
.collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)));
}
public DependencyGroup removeDependency(final RecipeIdentifier identifier) {
Preconditions.checkNotNull(identifier);
if (!dependencies.containsKey(identifier)) {
return this;
}
return new DependencyGroup(dependencies.entrySet()
.stream()
.filter(x -> !x.getKey().equals(identifier))
.collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)));
}
public boolean isSatisfiedBy(final ImmutableSet<RecipeVersionIdentifier> recipes) {
Preconditions.checkNotNull(recipes);
return dependencies.entrySet()
.stream()
.allMatch(x -> recipes.stream()
.anyMatch(y -> x.getKey().equals(y.project) &&
x.getValue().isSatisfiedBy(y.version)));
}
@Override
public int hashCode() {
return Objects.hash(dependencies);
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null || !(obj instanceof DependencyGroup)) {
return false;
}
final DependencyGroup other = (DependencyGroup) obj;
return Objects.equals(dependencies, other.dependencies);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("dependencies", dependencies)
.toString();
}
public static DependencyGroup of(final ImmutableMap<RecipeIdentifier, SemanticVersionRequirement> dependencies) {
return new DependencyGroup(dependencies);
}
public static DependencyGroup of() {
return new DependencyGroup(ImmutableMap.of());
}
}