package com.airlock.iam.base.misc.log;

import jakarta.annotation.Nullable;
import java.util.Objects;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;

public final class LogUtil {
   private static final Pattern CONTROL_CHARS_PATTERN = Pattern.compile("\\p{C}");
   private static final String LOG_STRING_MASKED_CHARS = "...";

   @Nullable
   public static String logSafeString(@Nullable String str) {
      return str == null ? null : CONTROL_CHARS_PATTERN.matcher(StringUtils.abbreviate(str, 200)).replaceAll("?");
   }

   @Nullable
   public static String logSafeString(@Nullable Object object) {
      return logSafeString(Objects.toString(object, null));
   }

   public static String quote(String unquoted) {
      return unquoted == null ? "[null]" : "\"" + unquoted + "\"";
   }

   public static String quote(Object unquoted) {
      return quote(Objects.toString(unquoted, null));
   }

   public static String logSafeQuote(Object object) {
      return quote(logSafeString(object));
   }

   public static String addSentence(String text, String sentenceToAdd) {
      return Strings.CS.endsWithAny(text, new CharSequence[]{".", "!", "?"}) ? text + " " + sentenceToAdd : text + ". " + sentenceToAdd;
   }

   public static String pluralize(int num, String word) {
      return num + " " + word + (num == 1 ? "" : "s");
   }

   public static String hideMiddlePart(String secretString, int nrOfLeadingChars, int nrOfTrailingChars) {
      Objects.requireNonNull(secretString, "secretString must not be null");
      return secretString.length() <= nrOfLeadingChars + nrOfTrailingChars
         ? secretString
         : StringUtils.left(secretString, nrOfLeadingChars) + "..." + StringUtils.right(secretString, nrOfTrailingChars);
   }

   public static String formatNanos(long nanos) {
      if (nanos < 100000L) {
         return String.format("%.3fms", nanos / 1000000.0);
      } else {
         return nanos < 5000000.0 ? String.format("%.1fms", nanos / 1000000.0) : String.format("%dms", nanos / 1000000L);
      }
   }

   private LogUtil() {
      throw new AssertionError();
   }
}
