package net.minecraft.server;
import com.google.common.collect.Maps;
import com.google.common.collect.UnmodifiableIterator;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
import com.mojang.brigadier.exceptions.Dynamic3CommandExceptionType;
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import javax.annotation.Nullable;
public class ArgumentBlock {
public static final SimpleCommandExceptionType a = new SimpleCommandExceptionType(new ChatMessage("argument.block.tag.disallowed", new Object[0]));
public static final DynamicCommandExceptionType b = new DynamicCommandExceptionType((object) -> {
return new ChatMessage("argument.block.id.invalid", new Object[]{object});
});
public static final Dynamic2CommandExceptionType c = new Dynamic2CommandExceptionType((object, object1) -> {
return new ChatMessage("argument.block.property.unknown", new Object[]{object, object1});
});
public static final Dynamic2CommandExceptionType d = new Dynamic2CommandExceptionType((object, object1) -> {
return new ChatMessage("argument.block.property.duplicate", new Object[]{object1, object});
});
public static final Dynamic3CommandExceptionType e = new Dynamic3CommandExceptionType((object, object1, object2) -> {
return new ChatMessage("argument.block.property.invalid", new Object[]{object, object2, object1});
});
public static final Dynamic2CommandExceptionType f = new Dynamic2CommandExceptionType((object, object1) -> {
return new ChatMessage("argument.block.property.novalue", new Object[]{object, object1});
});
public static final SimpleCommandExceptionType g = new SimpleCommandExceptionType(new ChatMessage("argument.block.property.unclosed", new Object[0]));
private static final Function<SuggestionsBuilder, CompletableFuture<Suggestions>> h = SuggestionsBuilder::buildFuture;
private final StringReader i;
private final boolean j;
private final Map<IBlockState<?>, Comparable<?>> k = Maps.newLinkedHashMap(); // CraftBukkit - stable
private final Map<String, String> l = Maps.newHashMap();
private MinecraftKey m = new MinecraftKey("");
private BlockStateList<Block, IBlockData> n;
private IBlockData o;
@Nullable
private NBTTagCompound p;
private MinecraftKey q = new MinecraftKey("");
private int r;
private Function<SuggestionsBuilder, CompletableFuture<Suggestions>> s;
public ArgumentBlock(StringReader stringreader, boolean flag) {
this.s = ArgumentBlock.h;
this.i = stringreader;
this.j = flag;
}
public Map<IBlockState<?>, Comparable<?>> getStateMap() {
return this.k;
}
@Nullable
public IBlockData getBlockData() {
return this.o;
}
@Nullable
public NBTTagCompound c() {
return this.p;
}
@Nullable
public MinecraftKey d() {
return this.q;
}
public ArgumentBlock a(boolean flag) throws CommandSyntaxException {
this.s = this::l;
if (this.i.canRead() && this.i.peek() == '#') {
this.f();
this.s = this::i;
if (this.i.canRead() && this.i.peek() == '[') {
this.h();
this.s = this::f;
}
} else {
this.e();
this.s = this::j;
if (this.i.canRead() && this.i.peek() == '[') {
this.g();
this.s = this::f;
}
}
if (flag && this.i.canRead() && this.i.peek() == '{') {
this.s = ArgumentBlock.h;
this.i();
}
return this;
}
private CompletableFuture<Suggestions> b(SuggestionsBuilder suggestionsbuilder) {
if (suggestionsbuilder.getRemaining().isEmpty()) {
suggestionsbuilder.suggest(String.valueOf(']'));
}
return this.d(suggestionsbuilder);
}
private CompletableFuture<Suggestions> c(SuggestionsBuilder suggestionsbuilder) {
if (suggestionsbuilder.getRemaining().isEmpty()) {
suggestionsbuilder.suggest(String.valueOf(']'));
}
return this.e(suggestionsbuilder);
}
private CompletableFuture<Suggestions> d(SuggestionsBuilder suggestionsbuilder) {
String s = suggestionsbuilder.getRemaining().toLowerCase(Locale.ROOT);
Iterator iterator = this.o.a().iterator();
while (iterator.hasNext()) {
IBlockState<?> iblockstate = (IBlockState) iterator.next();
if (!this.k.containsKey(iblockstate) && iblockstate.a().startsWith(s)) {
suggestionsbuilder.suggest(iblockstate.a() + '=');
}
}
return suggestionsbuilder.buildFuture();
}
private CompletableFuture<Suggestions> e(SuggestionsBuilder suggestionsbuilder) {
String s = suggestionsbuilder.getRemaining().toLowerCase(Locale.ROOT);
if (this.q != null && !this.q.getKey().isEmpty()) {
Tag<Block> tag = TagsBlock.a().a(this.q);
if (tag != null) {
Iterator iterator = tag.a().iterator();
while (iterator.hasNext()) {
Block block = (Block) iterator.next();
Iterator iterator1 = block.getStates().d().iterator();
while (iterator1.hasNext()) {
IBlockState<?> iblockstate = (IBlockState) iterator1.next();
if (!this.l.containsKey(iblockstate.a()) && iblockstate.a().startsWith(s)) {
suggestionsbuilder.suggest(iblockstate.a() + '=');
}
}
}
}
}
return suggestionsbuilder.buildFuture();
}
private CompletableFuture<Suggestions> f(SuggestionsBuilder suggestionsbuilder) {
if (suggestionsbuilder.getRemaining().isEmpty() && this.k()) {
suggestionsbuilder.suggest(String.valueOf('{'));
}
return suggestionsbuilder.buildFuture();
}
private boolean k() {
if (this.o != null) {
return this.o.getBlock().isTileEntity();
} else {
if (this.q != null) {
Tag<Block> tag = TagsBlock.a().a(this.q);
if (tag != null) {
Iterator iterator = tag.a().iterator();
while (iterator.hasNext()) {
Block block = (Block) iterator.next();
if (block.isTileEntity()) {
return true;
}
}
}
}
return false;
}
}
private CompletableFuture<Suggestions> g(SuggestionsBuilder suggestionsbuilder) {
if (suggestionsbuilder.getRemaining().isEmpty()) {
suggestionsbuilder.suggest(String.valueOf('='));
}
return suggestionsbuilder.buildFuture();
}
private CompletableFuture<Suggestions> h(SuggestionsBuilder suggestionsbuilder) {
if (suggestionsbuilder.getRemaining().isEmpty()) {
suggestionsbuilder.suggest(String.valueOf(']'));
}
if (suggestionsbuilder.getRemaining().isEmpty() && this.k.size() < this.o.a().size()) {
suggestionsbuilder.suggest(String.valueOf(','));
}
return suggestionsbuilder.buildFuture();
}
private static <T extends Comparable<T>> SuggestionsBuilder a(SuggestionsBuilder suggestionsbuilder, IBlockState<T> iblockstate) {
Iterator iterator = iblockstate.getValues().iterator();
while (iterator.hasNext()) {
T t0 = (T) iterator.next(); // CraftBukkit - decompile error
if (t0 instanceof Integer) {
suggestionsbuilder.suggest((Integer) t0);
} else {
suggestionsbuilder.suggest(iblockstate.a(t0));
}
}
return suggestionsbuilder;
}
private CompletableFuture<Suggestions> a(SuggestionsBuilder suggestionsbuilder, String s) {
boolean flag = false;
if (this.q != null && !this.q.getKey().isEmpty()) {
Tag<Block> tag = TagsBlock.a().a(this.q);
if (tag != null) {
Iterator iterator = tag.a().iterator();
while (iterator.hasNext()) {
Block block = (Block) iterator.next();
IBlockState<?> iblockstate = block.getStates().a(s);
if (iblockstate != null) {
a(suggestionsbuilder, iblockstate);
}
if (!flag) {
Iterator iterator1 = block.getStates().d().iterator();
while (iterator1.hasNext()) {
IBlockState<?> iblockstate1 = (IBlockState) iterator1.next();
if (!this.l.containsKey(iblockstate1.a())) {
flag = true;
break;
}
}
}
}
}
}
if (flag) {
suggestionsbuilder.suggest(String.valueOf(','));
}
suggestionsbuilder.suggest(String.valueOf(']'));
return suggestionsbuilder.buildFuture();
}
private CompletableFuture<Suggestions> i(SuggestionsBuilder suggestionsbuilder) {
if (suggestionsbuilder.getRemaining().isEmpty()) {
Tag<Block> tag = TagsBlock.a().a(this.q);
if (tag != null) {
boolean flag = false;
boolean flag1 = false;
Iterator iterator = tag.a().iterator();
while (iterator.hasNext()) {
Block block = (Block) iterator.next();
flag |= !block.getStates().d().isEmpty();
flag1 |= block.isTileEntity();
if (flag && flag1) {
break;
}
}
if (flag) {
suggestionsbuilder.suggest(String.valueOf('['));
}
if (flag1) {
suggestionsbuilder.suggest(String.valueOf('{'));
}
}
}
return this.k(suggestionsbuilder);
}
private CompletableFuture<Suggestions> j(SuggestionsBuilder suggestionsbuilder) {
if (suggestionsbuilder.getRemaining().isEmpty()) {
if (!this.o.getBlock().getStates().d().isEmpty()) {
suggestionsbuilder.suggest(String.valueOf('['));
}
if (this.o.getBlock().isTileEntity()) {
suggestionsbuilder.suggest(String.valueOf('{'));
}
}
return suggestionsbuilder.buildFuture();
}
private CompletableFuture<Suggestions> k(SuggestionsBuilder suggestionsbuilder) {
return ICompletionProvider.a((Iterable) TagsBlock.a().a(), suggestionsbuilder.createOffset(this.r).add(suggestionsbuilder));
}
private CompletableFuture<Suggestions> l(SuggestionsBuilder suggestionsbuilder) {
if (this.j) {
ICompletionProvider.a((Iterable) TagsBlock.a().a(), suggestionsbuilder, String.valueOf('#'));
}
ICompletionProvider.a((Iterable) IRegistry.BLOCK.keySet(), suggestionsbuilder);
return suggestionsbuilder.buildFuture();
}
public void e() throws CommandSyntaxException {
int i = this.i.getCursor();
this.m = MinecraftKey.a(this.i);
Block block = (Block) IRegistry.BLOCK.getOptional(this.m).orElseThrow(() -> {
this.i.setCursor(i);
return ArgumentBlock.b.createWithContext(this.i, this.m.toString());
});
this.n = block.getStates();
this.o = block.getBlockData();
}
public void f() throws CommandSyntaxException {
if (!this.j) {
throw ArgumentBlock.a.create();
} else {
this.s = this::k;
this.i.expect('#');
this.r = this.i.getCursor();
this.q = MinecraftKey.a(this.i);
}
}
public void g() throws CommandSyntaxException {
this.i.skip();
this.s = this::b;
this.i.skipWhitespace();
while (true) {
if (this.i.canRead() && this.i.peek() != ']') {
this.i.skipWhitespace();
int i = this.i.getCursor();
String s = this.i.readString();
IBlockState<?> iblockstate = this.n.a(s);
if (iblockstate == null) {
this.i.setCursor(i);
throw ArgumentBlock.c.createWithContext(this.i, this.m.toString(), s);
}
if (this.k.containsKey(iblockstate)) {
this.i.setCursor(i);
throw ArgumentBlock.d.createWithContext(this.i, this.m.toString(), s);
}
this.i.skipWhitespace();
this.s = this::g;
if (!this.i.canRead() || this.i.peek() != '=') {
throw ArgumentBlock.f.createWithContext(this.i, this.m.toString(), s);
}
this.i.skip();
this.i.skipWhitespace();
this.s = (suggestionsbuilder) -> {
return a(suggestionsbuilder, iblockstate).buildFuture();
};
int j = this.i.getCursor();
this.a(iblockstate, this.i.readString(), j);
this.s = this::h;
this.i.skipWhitespace();
if (!this.i.canRead()) {
continue;
}
if (this.i.peek() == ',') {
this.i.skip();
this.s = this::d;
continue;
}
if (this.i.peek() != ']') {
throw ArgumentBlock.g.createWithContext(this.i);
}
}
if (this.i.canRead()) {
this.i.skip();
return;
}
throw ArgumentBlock.g.createWithContext(this.i);
}
}
public void h() throws CommandSyntaxException {
this.i.skip();
this.s = this::c;
int i = -1;
this.i.skipWhitespace();
while (true) {
if (this.i.canRead() && this.i.peek() != ']') {
this.i.skipWhitespace();
int j = this.i.getCursor();
String s = this.i.readString();
if (this.l.containsKey(s)) {
this.i.setCursor(j);
throw ArgumentBlock.d.createWithContext(this.i, this.m.toString(), s);
}
this.i.skipWhitespace();
if (!this.i.canRead() || this.i.peek() != '=') {
this.i.setCursor(j);
throw ArgumentBlock.f.createWithContext(this.i, this.m.toString(), s);
}
this.i.skip();
this.i.skipWhitespace();
this.s = (suggestionsbuilder) -> {
return this.a(suggestionsbuilder, s);
};
i = this.i.getCursor();
String s1 = this.i.readString();
this.l.put(s, s1);
this.i.skipWhitespace();
if (!this.i.canRead()) {
continue;
}
i = -1;
if (this.i.peek() == ',') {
this.i.skip();
this.s = this::e;
continue;
}
if (this.i.peek() != ']') {
throw ArgumentBlock.g.createWithContext(this.i);
}
}
if (this.i.canRead()) {
this.i.skip();
return;
}
if (i >= 0) {
this.i.setCursor(i);
}
throw ArgumentBlock.g.createWithContext(this.i);
}
}
public void i() throws CommandSyntaxException {
this.p = (new MojangsonParser(this.i)).f();
}
private <T extends Comparable<T>> void a(IBlockState<T> iblockstate, String s, int i) throws CommandSyntaxException {
Optional<T> optional = iblockstate.b(s);
if (optional.isPresent()) {
this.o = (IBlockData) this.o.set(iblockstate, (T) optional.get()); // CraftBukkit - decompile error
this.k.put(iblockstate, optional.get());
} else {
this.i.setCursor(i);
throw ArgumentBlock.e.createWithContext(this.i, this.m.toString(), iblockstate.a(), s);
}
}
public static String a(IBlockData iblockdata) {
StringBuilder stringbuilder = new StringBuilder(IRegistry.BLOCK.getKey(iblockdata.getBlock()).toString());
if (!iblockdata.a().isEmpty()) {
stringbuilder.append('[');
boolean flag = false;
for (UnmodifiableIterator unmodifiableiterator = iblockdata.getStateMap().entrySet().iterator(); unmodifiableiterator.hasNext(); flag = true) {
Entry<IBlockState<?>, Comparable<?>> entry = (Entry) unmodifiableiterator.next();
if (flag) {
stringbuilder.append(',');
}
a(stringbuilder, (IBlockState) entry.getKey(), (Comparable) entry.getValue());
}
stringbuilder.append(']');
}
return stringbuilder.toString();
}
private static <T extends Comparable<T>> void a(StringBuilder stringbuilder, IBlockState<T> iblockstate, Comparable<?> comparable) {
stringbuilder.append(iblockstate.a());
stringbuilder.append('=');
stringbuilder.append(iblockstate.a((T) comparable)); // CraftBukkit - decompile error
}
public CompletableFuture<Suggestions> a(SuggestionsBuilder suggestionsbuilder) {
return (CompletableFuture) this.s.apply(suggestionsbuilder.createOffset(this.i.getCursor()));
}
public Map<String, String> j() {
return this.l;
}
}