content: package featurecat.lizzie.analysis;
  
  import org.apache.commons.collections4.CollectionUtils;
  import org.apache.commons.lang3.StringUtils;
  import org.eclipse.collections.api.list.primitive.MutableDoubleList;
  import org.eclipse.collections.api.list.primitive.MutableIntList;
  import org.eclipse.collections.impl.factory.Lists;
  import org.eclipse.collections.impl.list.mutable.primitive.DoubleArrayList;
  import org.eclipse.collections.impl.list.mutable.primitive.IntArrayList;
  
  import java.util.Collections;
  import java.util.List;
  import java.util.concurrent.ExecutionException;
  
  public interface GtpCommand {
      default GtpFuture play(String color, String move) {
          if (StringUtils.equalsIgnoreCase(color, "B") || StringUtils.equalsIgnoreCase(color, "W")) {
              return postCommand(String.format("play %s %s", color, move));
          } else {
              throw new IllegalArgumentException("The stone color must be BLACK(B) or WHITE(W), but is " + color);
          }
      }
  
      default GtpFuture undo() {
          return postCommand("undo");
      }
  
      default GtpFuture clearBoard() {
          return postCommand("clear_board");
      }
  
      default List<String> sendCommand(String command) {
          GtpFuture commandFuture = postCommand(command);
          try {
              return commandFuture.get();
          } catch (InterruptedException | ExecutionException e) {
              return Collections.emptyList();
          }
      }
  
      GtpFuture postCommand(String command);
  
      static boolean isSuccessfulResponse(List<String> response) {
          boolean result = false;
  
          if (CollectionUtils.isNotEmpty(response)) {
              String beginElement = response.get(0);
              if (beginElement.startsWith("=")) {
                  result = true;
              }
          }
  
          return result;
      }
  
      static String getLineWithoutResponseHeader(List<String> response, int lineIndex) {
          if (lineIndex < 0 || lineIndex >= (response == null ? -1 : response.size())) {
              return "";
          }
          String line = StringUtils.defaultString(response.get(lineIndex));
          if (lineIndex == 0) {
              return StringUtils.removeFirst(line, "^[=?]\\d*\\s*");
          } else {
              return line;
          }
      }
  
      static List<String> removeResponseHeaderInPlace(List<String> response) {
          if (CollectionUtils.isNotEmpty(response)) {
              String beginElement = response.get(0);
              if (beginElement.startsWith("=") || beginElement.startsWith("?")) {
                  beginElement = StringUtils.removeFirst(beginElement, "^[=?]\\d*\\s*");
                  response.set(0, beginElement);
              }
          }
  
          return response;
      }
  
      static List<String> removeResponseHeaderCopy(List<String> response) {
          return removeResponseHeaderInPlace(Lists.mutable.ofAll(response));
      }
  
      static MutableIntList parseResponseIntTable(List<String> response) {
          MutableIntList result = new IntArrayList();
          for (String lineString : response) {
              String[] line = lineString.split("\\s+");
              for (String lineItemString : line) {
                  try {
                      int lineItem = Integer.parseInt(lineItemString);
                      result.add(lineItem);
                  } catch (NumberFormatException e) {
                      // ignore
                  }
              }
          }
  
          return result;
      }
  
      static MutableDoubleList parseResponseDoubleTable(List<String> response) {
          MutableDoubleList result = new DoubleArrayList();
          for (String lineString : response) {
              String[] line = lineString.split("\\s+");
              for (String lineItemString : line) {
                  try {
                      double lineItem = Double.parseDouble(lineItemString);
                      result.add(lineItem);
                  } catch (NumberFormatException e) {
                      // ignore
                  }
              }
          }
  
          return result;
      }
  }
  