content: package org.allaymc.server.command.tree.node;
  
  import org.allaymc.api.block.property.type.BlockPropertyType;
  import org.allaymc.api.block.type.BlockType;
  import org.allaymc.api.command.tree.CommandContext;
  import org.allaymc.api.command.tree.CommandNode;
  import org.allaymc.api.message.TrKeys;
  import org.allaymc.api.utils.AllayStringUtils;
  import org.cloudburstmc.protocol.bedrock.data.command.CommandParam;
  import org.cloudburstmc.protocol.bedrock.data.command.CommandParamData;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  
  /**
   * @author daoge_cmd
   */
  public class BlockPropertyValuesNode extends BaseNode {
      public BlockPropertyValuesNode(String name, CommandNode parent, List<BlockPropertyType.BlockPropertyValue<?, ?, ?>> defaultValue) {
          super(name, parent, defaultValue);
          if (!(parent instanceof BlockTypeNode)) {
              throw new IllegalArgumentException("BlockPropertyValuesNode must be a child of BlockTypeNode");
          }
      }
  
      @Override
      public boolean match(CommandContext context) {
          var arg = context.queryArg();
          if (!(arg.startsWith("[") && arg.endsWith("]"))) {
              return false;
          }
  
          var substring = arg.substring(1, arg.length() - 1);
          if (substring.isBlank()) {
              context.putResult(List.of());
              context.popArg();
              return true;
          }
  
          BlockType<?> blockType = context.getResult(context.getCurrentResultIndex() - 1);
          var propertyValues = new HashMap<BlockPropertyType<?>, BlockPropertyType.BlockPropertyValue<?, ?, ?>>();
          for (var propertyStr : AllayStringUtils.fastSplit(substring, ",")) {
              var split = AllayStringUtils.fastTwoPartSplit(propertyStr, "=", "");
              var key = removeQuote(split[0]);
              var value = removeQuote(split[1]);
              var propertyType = blockType.getProperties().get(key);
              if (propertyType == null) {
                  context.addError("%" + TrKeys.MC_COMMANDS_BLOCKSTATE_TYPEERROR, key);
                  return false;
              }
              BlockPropertyType.BlockPropertyValue<?, ?, ?> propertyValue;
              try {
                  propertyValue = propertyType.tryCreateValue(value);
              } catch (IllegalArgumentException e) {
                  context.addError("%" + TrKeys.MC_COMMANDS_BLOCKSTATE_VALUEERROR, key + "=" + value);
                  return false;
              }
              propertyValues.put(propertyType, propertyValue);
          }
  
          for (var propertyValue : blockType.getDefaultState().getPropertyValues().values()) {
              propertyValues.putIfAbsent(propertyValue.getPropertyType(), propertyValue);
          }
  
          context.putResult(new ArrayList<>(propertyValues.values()));
          context.popArg();
          return true;
      }
  
      protected String removeQuote(String str) {
          if (str.startsWith("\"") && str.endsWith("\"")) {
              return str.substring(1, str.length() - 1);
          }
          return str;
      }
  
      @Override
      public CommandParamData toNetworkData() {
          var data = super.toNetworkData();
          data.setType(CommandParam.BLOCK_STATES);
          return data;
      }
  }
  