package com.prezi.grub.gradle.config;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import groovy.lang.Closure;
import groovy.lang.GroovyObjectSupport;
import groovy.lang.MissingPropertyException;
import org.codehaus.groovy.runtime.StringGroovyMethods;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Map;
public class ParameterContainer extends GroovyObjectSupport {
private final Map<String, Parameter> parameters = Maps.newLinkedHashMap();
private Map<String, Object> resolvedValues;
@SuppressWarnings("UnusedDeclaration")
public Object methodMissing(String name, Object args) {
if (parameters.containsKey(name)) {
throw new IllegalArgumentException("Parameter with name already registered: " + name);
}
Closure<?> closure = (Closure<?>) ((Object[]) args)[0];
Parameter parameter = new Parameter(name);
parameters.put(name, parameter);
closure.setDelegate(parameter);
closure.setResolveStrategy(Closure.DELEGATE_ONLY);
return closure.call(parameter);
}
@SuppressWarnings("UnusedDeclaration")
public Object propertyMissing(String name) {
if (resolvedValues.containsKey(name)) {
return resolvedValues.get(name);
}
throw new MissingPropertyException(name, ParameterContainer.class);
}
public Map<String, Object> resolve(Reader reader) throws IOException {
BufferedReader input = new BufferedReader(reader);
if (resolvedValues == null) {
resolvedValues = Maps.newLinkedHashMap();
for (Parameter parameter : parameters.values()) {
String title = parameter.getTitle();
if (Strings.isNullOrEmpty(title)) {
title = parameter.getName();
}
String description = parameter.getDescription();
boolean required = parameter.isRequired();
Object value = getParameterValue(parameter);
if (parameter.isPrompt()) {
StringBuilder prompt = new StringBuilder();
if (description != null) {
prompt.append(description).append(System.lineSeparator());
}
prompt.append(title);
if (required) {
prompt.append(" (required)");
}
if (value != null) {
prompt.append(" [").append(value).append(']');
}
prompt.append(": ");
while (true) {
System.out.print(prompt);
System.out.flush();
String userInput = input.readLine();
if (Strings.isNullOrEmpty(userInput)) {
if (required && value == null) {
System.out.println("Parameter '" + parameter + "' is required.");
continue;
}
} else {
Class<?> type = parameter.getType();
if (type == null && value != null) {
type = value.getClass();
} else {
type = String.class;
}
value = StringGroovyMethods.asType(userInput, type);
}
break;
}
}
resolvedValues.put(parameter.getName(), value);
}
}
return resolvedValues;
}
private Object getParameterValue(Parameter parameter) {
Closure<?> value = parameter.getValue();
if (value == null) {
return null;
}
Closure<?> clone = (Closure<?>) value.clone();
clone.setDelegate(this);
clone.setResolveStrategy(Closure.DELEGATE_ONLY);
return clone.call();
}
}