// Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.utils;

import com.android.tools.r8.errors.Unreachable;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringUtils {
  public static char[] EMPTY_CHAR_ARRAY = {};
  public static final String[] EMPTY_ARRAY = {};
  public static final String LINE_SEPARATOR = System.getProperty("line.separator");
  public static final char BOM = '\uFEFF';

  public enum BraceType {
    PARENS,
    SQUARE,
    TUBORG,
    NONE;

    public String left() {
      switch (this) {
        case PARENS: return "(";
        case SQUARE: return "[";
        case TUBORG: return "{";
        case NONE: return "";
        default: throw new Unreachable("Invalid brace type: " + this);
      }
    }

    public String right() {
      switch (this) {
        case PARENS: return ")";
        case SQUARE: return "]";
        case TUBORG: return "}";
        case NONE: return "";
        default: throw new Unreachable("Invalid brace type: " + this);
      }
    }
  }

  public static String toASCIIString(String s) {
    StringBuilder builder = new StringBuilder();
    for (char ch : s.toCharArray()) {
      if (0x1f < ch && ch < 0x7f) {  // 0 - 0x1f and 0x7f are control characters.
        builder.append(ch);
      } else {
        builder.append("\\u").append(StringUtils.hexString(ch, 4, false));
      }
    }
    return builder.toString();
  }

  public static boolean appendNonEmpty(
      StringBuilder builder, String pre, Object item, String post) {
    if (item == null) {
      return false;
    }
    String text = item.toString();
    if (!text.isEmpty()) {
      if (pre != null) {
        builder.append(pre);
      }
      builder.append(text);
      if (post != null) {
        builder.append(post);
      }
      return true;
    }
    return false;
  }

  public static StringBuilder appendIndent(StringBuilder builder, String subject, int indent) {
    for (int i = 0; i < indent; i++) {
      builder.append(" ");
    }
    builder.append(subject);
    return builder;
  }

  public static StringBuilder appendLeftPadded(StringBuilder builder, String subject, int width) {
    for (int i = subject.length(); i < width; i++) {
      builder.append(" ");
    }
    builder.append(subject);
    return builder;
  }

  public static StringBuilder appendRightPadded(StringBuilder builder, String subject, int width) {
    builder.append(subject);
    for (int i = subject.length(); i < width; i++) {
      builder.append(" ");
    }
    return builder;
  }

  public static <T> StringBuilder append(StringBuilder builder, Collection<T> collection) {
    return append(builder, collection, ", ", BraceType.PARENS);
  }

  public static <T> StringBuilder append(
      StringBuilder builder, Iterable<T> collection, String seperator, BraceType brace) {
    builder.append(brace.left());
    boolean first = true;
    for (T element : collection) {
      if (first) {
        first = false;
      } else {
        builder.append(seperator);
      }
      builder.append(element);
    }
    builder.append(brace.right());
    return builder;
  }

  public static String join(String separator, String... strings) {
    return join(separator, Arrays.asList(strings));
  }

  public static <T> String join(String separator, Iterable<T> iterable) {
    return join(separator, iterable, BraceType.NONE);
  }

  public static <T> String join(String separator, Iterable<T> iterable, Function<T, String> fn) {
    return join(separator, iterable, fn, BraceType.NONE);
  }

  public static <T> String join(String separator, Iterable<T> iterable, BraceType brace) {
    return join(separator, iterable, Object::toString, brace);
  }

  public static <T> String join(
      String separator, Iterable<T> iterable, Function<T, String> fn, BraceType brace) {
    StringBuilder builder = new StringBuilder();
    append(builder, IterableUtils.transform(iterable, fn), separator, brace);
    return builder.toString();
  }

  public static String lines(List<String> lines) {
    StringBuilder builder = new StringBuilder();
    for (String line : lines) {
      builder.append(line).append(LINE_SEPARATOR);
    }
    return builder.toString();
  }

  public static String lines(String... lines) {
    return lines(Arrays.asList(lines));
  }

  public static String withNativeLineSeparator(String s) {
    s = s.replace("\r\n", "\n");
    if (LINE_SEPARATOR.equals("\r\n")) {
      return s.replace("\n", "\r\n");
    } else {
      assert LINE_SEPARATOR.equals("\n");
      return s;
    }
  }

  public static String joinLines(String... lines) {
    return join(LINE_SEPARATOR, lines);
  }

  public static <T> String joinLines(Collection<T> collection) {
    return join(LINE_SEPARATOR, collection, BraceType.NONE);
  }

  public static List<String> splitLines(String content) {
    int length = content.length();
    List<String> lines = new ArrayList<>();
    int start = 0;
    for (int i = 0; i < length; i++) {
      char c = content.charAt(i);
      int end = i;
      if (c == '\r' && i + 1 < length && content.charAt(i + 1) == '\n') {
        ++i;
      } else if (c != '\n') {
        continue;
      }
      lines.add(content.substring(start, end));
      start = i + 1;
    }
    if (start < length) {
      String line = content.substring(start);
      if (!line.isEmpty()) {
        lines.add(line);
      }
    }
    return lines;
  }

  public static String zeroPrefix(int i, int width) {
    return zeroPrefixString(Integer.toString(i), width);
  }

  private static String zeroPrefixString(String s, int width) {
    String prefix = "0000000000000000";
    assert(width <= prefix.length());
    int prefixLength = width - s.length();
    if (prefixLength > 0) {
      StringBuilder builder = new StringBuilder();
      builder.append(prefix, 0, prefixLength);
      builder.append(s);
      return builder.toString();
    } else {
      return s;
    }
  }

  public static String hexString(int value, int width) {
    return hexString(value, width, true);
  }

  public static String hexString(int value, int width, boolean zeroXPrefix) {
    assert(0 <= width && width <= 8);
    String prefix = zeroXPrefix ? "0x" : "";
    String hex = Integer.toHexString(value);
    if (value >= 0) {
      return prefix + zeroPrefixString(hex, width);
    } else {
      // Negative ints are always formatted as 8 characters.
      assert(hex.length() == 8);
      return prefix + hex;
    }
  }

  public static String hexString(long value, int width) {
    return hexString(value, width, true);
  }

  public static String hexString(long value, int width, boolean zeroXPrefix) {
    assert(0 <= width && width <= 16);
    String prefix = zeroXPrefix ? "0x" : "";
    String hex = Long.toHexString(value);
    if (value >= 0) {
      return prefix + zeroPrefixString(hex, width);
    } else {
      // Negative longs are always formatted as 16 characters.
      assert(hex.length() == 16);
      return prefix + hex;
    }
  }

  public static String computeMD5Hash(String name) {
    byte[] digest = null;
    try {
      MessageDigest m = MessageDigest.getInstance("MD5");
      m.reset();
      m.update(name.getBytes());
      digest = m.digest();
    } catch (NoSuchAlgorithmException e) {
      throw new RuntimeException(e);
    }
    return Arrays.toString(digest);
  }


  public static String times(String string, int count) {
    StringBuilder builder = new StringBuilder();
    while (--count >= 0) {
      builder.append(string);
    }
    return builder.toString();
  }

  public static boolean isBOM(int codePoint) {
    return codePoint == BOM;
  }

  public static boolean isWhitespace(int codePoint) {
    return Character.isWhitespace(codePoint) || isBOM(codePoint);
  }

  public static String stripLeadingBOM(String s) {
    if (s.length() > 0 && s.charAt(0) == StringUtils.BOM) {
      return s.substring(1);
    } else {
      return s;
    }
  }

  public static String trim(String s) {
    int beginIndex = 0;
    int endIndex = s.length();
    while (beginIndex < endIndex && isWhitespace(s.charAt(beginIndex))) {
      beginIndex++;
    }
    while (endIndex - 1 > beginIndex && isWhitespace(s.charAt(endIndex - 1))) {
      endIndex--;
    }
    if (beginIndex > 0 || endIndex < s.length()) {
      return s.substring(beginIndex, endIndex);
    } else {
      return s;
    }
  }

  /** Returns true if {@param s} only contains the characters [0-9]. */
  public static boolean onlyContainsDigits(String s) {
    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);
      if (!Character.isDigit(c)) {
        return false;
      }
    }
    return true;
  }

  public static char lastChar(String s) {
    return charFromEnd(s, 0);
  }

  public static char charFromEnd(String s, int charsFromEnd) {
    assert s.length() > charsFromEnd;
    return s.charAt(s.length() - (charsFromEnd + 1));
  }

  public static int firstNonWhitespaceCharacter(String string) {
    for (int i = 0; i < string.length(); i++) {
      if (!isWhitespace(string.charAt(i))) {
        return i;
      }
    }
    return string.length();
  }

  public static String replaceAll(String subject, String target, String replacement) {
    return subject.replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement));
  }

  public static String stacktraceAsString(Throwable throwable) {
    StringWriter sw = new StringWriter();
    throwable.printStackTrace(new PrintWriter(sw));
    return sw.toString();
  }

  public static String capitalize(String stringToCapitalize) {
    if (stringToCapitalize == null || stringToCapitalize.isEmpty()) {
      return stringToCapitalize;
    }
    return stringToCapitalize.substring(0, 1).toUpperCase() + stringToCapitalize.substring(1);
  }
}
