// Copyright (c) 2019, 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 static com.android.tools.r8.utils.StringUtils.EMPTY_CHAR_ARRAY;

import com.google.common.collect.Sets;
import java.util.Arrays;
import java.util.Set;

public class SymbolGenerationUtils {

  public enum MixedCasing {
    USE_MIXED_CASE,
    DONT_USE_MIXED_CASE
  }

  public static Set<String> PRIMITIVE_TYPE_NAMES =
      Sets.newHashSet(
          "boolean", "byte", "char", "double", "float", "int", "long", "short", "void", "it");

  // These letters are used not creating fresh names to output and not for parsing dex/class files.
  private static final char[] IDENTIFIER_CHARACTERS =
      "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
  private static final int NUMBER_OF_CHARACTERS = IDENTIFIER_CHARACTERS.length;
  private static final int NUMBER_OF_CHARACTERS_MINUS_CAPITAL_LETTERS = NUMBER_OF_CHARACTERS - 26;
  private static final int NON_ALLOWED_FIRST_CHARACTERS = 10;

  public static String numberToIdentifier(int nameCount, MixedCasing mixedCasing) {
    return numberToIdentifier(nameCount, mixedCasing, EMPTY_CHAR_ARRAY, false);
  }

  public static String numberToIdentifier(int nameCount, MixedCasing mixedCasing, char[] prefix) {
    return numberToIdentifier(nameCount, mixedCasing, prefix, false);
  }

  public static String numberToIdentifier(
      int nameCount, MixedCasing mixedCasing, char[] prefix, boolean addSemicolon) {
    int size = 1;
    int number = nameCount;
    int maximumNumberOfCharacters =
        mixedCasing == MixedCasing.USE_MIXED_CASE
            ? NUMBER_OF_CHARACTERS
            : NUMBER_OF_CHARACTERS_MINUS_CAPITAL_LETTERS;
    int firstNumberOfCharacters = maximumNumberOfCharacters - NON_ALLOWED_FIRST_CHARACTERS;
    int availableCharacters = firstNumberOfCharacters;
    // We first do an initial computation to find the size of the resulting string to allocate an
    // array that will fit in length.
    while (number > availableCharacters) {
      number = (number - 1) / availableCharacters;
      availableCharacters = maximumNumberOfCharacters;
      size++;
    }
    size += addSemicolon ? 1 : 0;
    char characters[] = Arrays.copyOfRange(prefix, 0, prefix.length + size);
    number = nameCount;

    int i = prefix.length;
    availableCharacters = firstNumberOfCharacters;
    int firstLetterPadding = NON_ALLOWED_FIRST_CHARACTERS;
    while (number > availableCharacters) {
      characters[i++] =
          IDENTIFIER_CHARACTERS[(number - 1) % availableCharacters + firstLetterPadding];
      number = (number - 1) / availableCharacters;
      availableCharacters = maximumNumberOfCharacters;
      firstLetterPadding = 0;
    }
    characters[i++] = IDENTIFIER_CHARACTERS[number - 1 + firstLetterPadding];
    if (addSemicolon) {
      characters[i++] = ';';
    }
    assert i == characters.length;
    assert !Character.isDigit(characters[prefix.length]);

    return new String(characters);
  }
}
