package com.sora.util.akatsuki;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.stream.Collectors;
import javax.lang.model.element.Modifier;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.squareup.javapoet.ArrayTypeName;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.FieldSpec.Builder;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
public class TestField {
public final Class<?> clazz;
public final Class<?>[] parameters;
public final String name;
public final String initializer;
public final EnumSet<Modifier> modifiers = EnumSet.noneOf(Modifier.class);
public TestField(Class<?> clazz, Class<?>... parameters) {
this.clazz = clazz;
this.parameters = parameters;
this.name = "_" + createName(clazz, parameters);
this.initializer = null;
}
public TestField(Class<?> clazz, String name, Class<?>... parameters) {
this.clazz = clazz;
this.parameters = parameters;
this.name = name;
this.initializer = null;
}
public TestField(Class<?> clazz, String name, String initializer, Class<?>... parameters) {
this.clazz = clazz;
this.parameters = parameters;
this.name = name;
this.initializer = initializer;
}
private static String createName(Class<?> clazz, Class<?>... parameters) {
if (clazz.isArray()) {
return createName(clazz.getComponentType(), parameters) + "Array";
} else {
return parameters.length == 0 ? clazz.getSimpleName()
: Arrays.stream(parameters).map(p -> createName(p))
.collect(Collectors.joining()) + createName(clazz);
}
}
public boolean generic() {
return parameters.length > 0;
}
public TypeName typeName() {
if (generic()) {
Class<?> rawType = clazz.isArray() ? clazz.getComponentType() : clazz;
final ParameterizedTypeName typeName = ParameterizedTypeName.get(rawType, parameters);
return clazz.isArray() ? ArrayTypeName.of(typeName) : typeName;
} else {
return TypeName.get(clazz);
}
}
public TestField appendModifier(Modifier... modifiers) {
this.modifiers.addAll(Arrays.asList(modifiers));
return this;
}
protected Builder fieldSpecBuilder() {
final Builder builder = FieldSpec.builder(typeName(), name);
if (initializer != null)
builder.initializer(initializer);
builder.addModifiers(modifiers.toArray(new Modifier[modifiers.size()]));
return builder;
}
public final FieldSpec createFieldSpec() {
return fieldSpecBuilder().build();
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
TestField field = (TestField) o;
return Objects.equal(clazz, field.clazz) && Objects.equal(parameters, field.parameters)
&& Objects.equal(name, field.name);
}
@Override
public int hashCode() {
return Objects.hashCode(clazz, parameters, name);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this).add("clazz", clazz).add("parameters", parameters)
.add("name", name).toString();
}
}