package org.icij.task;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
public class Option<V> {
private static class DefaultSupplier<V> implements Supplier<List<V>> {
private final List<V> values = new LinkedList<>();
@Override
public List<V> get() {
return values;
}
}
private final String name;
private Character code = null;
private String description = null;
private String parameter = null;
protected Supplier<List<V>> values = new DefaultSupplier<>();
protected final Function<Option<V>, OptionParser<V>> parser;
public Option(final String name, final Function<Option<V>, OptionParser<V>> parser) {
this.name = name;
this.parser = parser;
}
public Option<V> code(final Character code) {
this.code = code;
return this;
}
public Option<V> code(final String code) {
if (!code.isEmpty()) {
this.code = code.toCharArray()[0];
}
return this;
}
public Option<V> describe(final String description) {
this.description = description;
return this;
}
public String description() {
return description;
}
public String name() {
return name;
}
public Character code() {
return code;
}
public String parameter() {
return parameter;
}
public Option<V> parameter(final String parameter) {
this.parameter = parameter;
return this;
}
public synchronized Optional<V> value() {
final List<V> values = this.values.get();
if (!values.isEmpty()) {
return Optional.of(values.get(0));
}
return Optional.empty();
}
public synchronized List<V> values() {
return this.values.get();
}
public synchronized Option<V> update(final V value) {
final List<V> values = this.values.get();
values.clear();
values.add(value);
return this;
}
public synchronized Option<V> update(final List<V> values) {
this.values.get().clear();
this.values.get().addAll(values);
return this;
}
public synchronized Option<V> update(final Supplier<List<V>> supplier) {
values = supplier;
return this;
}
public synchronized <R> Optional<R> value(final Function<V, R> parser) {
final List<V> values = this.values.get();
if (values.isEmpty()) {
return Optional.empty();
}
return Optional.of(parser.apply(values.get(0)));
}
public synchronized <R> Collection<R> values(final Function<V, R> parser) {
final List<V> values = this.values.get();
final Collection<R> results = new ArrayList<>(values.size());
for (V value : values) {
results.add(parser.apply(value));
}
return results;
}
public OptionParser<V> parse() {
return parser.apply(this);
}
}