/**
  * Get the name from a UUID.
  *
  * @param owner
  * @return The player's name, None, Everyone or Unknown
  */
 public static String getName(UUID owner) {
   if (owner == null) {
     return C.NONE.s();
   }
   if (owner.equals(DBFunc.everyone)) {
     return C.EVERYONE.s();
   }
   String name = UUIDHandler.getName(owner);
   if (name == null) {
     return C.UNKNOWN.s();
   }
   return name;
 }
  /**
   * Format a string with plot information.
   *
   * @param info
   * @param plot
   * @param player
   * @param full
   * @param whenDone
   */
  public static void format(
      String info, Plot plot, PlotPlayer player, boolean full, RunnableVal<String> whenDone) {
    int num = plot.getConnectedPlots().size();
    String alias = !plot.getAlias().isEmpty() ? plot.getAlias() : C.NONE.s();
    Location bot = plot.getCorners()[0];
    String biome = WorldUtil.IMP.getBiome(plot.getArea().worldname, bot.getX(), bot.getZ());
    String trusted = getPlayerList(plot.getTrusted());
    String members = getPlayerList(plot.getMembers());
    String denied = getPlayerList(plot.getDenied());
    String seen;
    if (Settings.Enabled_Components.PLOT_EXPIRY) {
      if (plot.isOnline()) {
        seen = C.NOW.s();
      } else {
        int time = (int) (ExpireManager.IMP.getAge(plot) / 1000);
        seen = time != 0 ? secToTime(time) : C.UNKNOWN.s();
      }
    } else {
      seen = C.NEVER.s();
    }
    Optional<String> descriptionFlag = plot.getFlag(Flags.DESCRIPTION);
    String description =
        descriptionFlag.isPresent()
            ? Flags.DESCRIPTION.valueToString(descriptionFlag.get())
            : C.NONE.s();

    StringBuilder flags = new StringBuilder();
    HashMap<Flag<?>, Object> flagMap =
        FlagManager.getPlotFlags(plot.getArea(), plot.getSettings(), true);
    if (flagMap.isEmpty()) {
      flags.append(C.NONE.s());
    } else {
      String prefix = "";
      for (Map.Entry<Flag<?>, Object> entry : flagMap.entrySet()) {
        flags.append(prefix).append(C.PLOT_FLAG_LIST.f(entry.getKey().getName(), entry.getValue()));
        prefix = ", ";
      }
    }
    boolean build = plot.isAdded(player.getUUID());
    String owner = plot.getOwners().isEmpty() ? "unowned" : getPlayerList(plot.getOwners());
    info = info.replace("%id%", plot.getId().toString());
    info = info.replace("%alias%", alias);
    info = info.replace("%num%", String.valueOf(num));
    info = info.replace("%desc%", description);
    info = info.replace("%biome%", biome);
    info = info.replace("%owner%", owner);
    info = info.replace("%members%", members);
    info = info.replace("%player%", player.getName());
    info = info.replace("%trusted%", trusted);
    info = info.replace("%helpers%", members);
    info = info.replace("%denied%", denied);
    info = info.replace("%seen%", seen);
    info = info.replace("%flags%", flags);
    info = info.replace("%build%", String.valueOf(build));
    info = info.replace("%desc%", "No description set.");
    if (info.contains("%rating%")) {
      String newInfo = info;
      TaskManager.runTaskAsync(
          () -> {
            int max = 10;
            if (Settings.Ratings.CATEGORIES != null && !Settings.Ratings.CATEGORIES.isEmpty()) {
              max = 8;
            }
            String info1;
            if (full
                && Settings.Ratings.CATEGORIES != null
                && Settings.Ratings.CATEGORIES.size() > 1) {
              double[] ratings = getAverageRatings(plot);
              String rating = "";
              String prefix = "";
              for (int i = 0; i < ratings.length; i++) {
                rating +=
                    prefix
                        + Settings.Ratings.CATEGORIES.get(i)
                        + '='
                        + String.format("%.1f", ratings[i]);
                prefix = ",";
              }
              info1 = newInfo.replaceAll("%rating%", rating);
            } else {
              info1 =
                  newInfo.replaceAll(
                      "%rating%", String.format("%.1f", plot.getAverageRating()) + '/' + max);
            }
            whenDone.run(info1);
          });
      return;
    }
    whenDone.run(info);
  }