// Copyright (c) 2020, 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.synthesis;

import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.DescriptorUtils;

public class SyntheticNaming {

  /**
   * Enumeration of all kinds of synthetic items.
   *
   * <p>The synthetic kinds are used to provide hinting about what a synthetic item represents. The
   * kinds must *not* be used be the compiler and are only meant for "debugging". The compiler and
   * its test may use the kind information as part of asserting properties of the compiler. The kind
   * will be put into any non-minified synthetic name and thus the kind "descriptor" must be a
   * distinct for each kind.
   */
  public enum SyntheticKind {
    // Class synthetics.
    LAMBDA("Lambda", false),
    // Method synthetics.
    BACKPORT("Backport", true),
    STATIC_INTERFACE_CALL("StaticInterfaceCall", true),
    TO_STRING_IF_NOT_NULL("ToStringIfNotNull", true),
    THROW_CCE_IF_NOT_NULL("ThrowCCEIfNotNull", true),
    TWR_CLOSE_RESOURCE("TwrCloseResource", true),
    SERVICE_LOADER("ServiceLoad", true);

    public final String descriptor;
    public final boolean isSingleSyntheticMethod;

    SyntheticKind(String descriptor, boolean isSingleSyntheticMethod) {
      this.descriptor = descriptor;
      this.isSingleSyntheticMethod = isSingleSyntheticMethod;
    }

    public static SyntheticKind fromDescriptor(String descriptor) {
      for (SyntheticKind kind : values()) {
        if (kind.descriptor.equals(descriptor)) {
          return kind;
        }
      }
      return null;
    }
  }

  /**
   * The internal synthetic class separator is only used for representing synthetic items during
   * compilation. In particular, this separator must never be used to write synthetic classes to the
   * final compilation result.
   */
  private static final String INTERNAL_SYNTHETIC_CLASS_SEPARATOR = "-$$InternalSynthetic";
  /**
   * The external synthetic class separator is used when writing classes. It may appear in types
   * during compilation as the output of a compilation may be the input to another.
   */
  private static final String EXTERNAL_SYNTHETIC_CLASS_SEPARATOR = "-$$ExternalSynthetic";
  /** Method prefix when generating synthetic methods in a class. */
  static final String INTERNAL_SYNTHETIC_METHOD_PREFIX = "m";

  // TODO(b/158159959): Remove usage of name-based identification.
  public static boolean isSyntheticName(String typeName) {
    return typeName.contains(INTERNAL_SYNTHETIC_CLASS_SEPARATOR)
        || typeName.contains(EXTERNAL_SYNTHETIC_CLASS_SEPARATOR);
  }

  static DexType createInternalType(
      SyntheticKind kind, SynthesizingContext context, String id, DexItemFactory factory) {
    return createType(
        INTERNAL_SYNTHETIC_CLASS_SEPARATOR,
        kind,
        context.getSynthesizingContextType(),
        id,
        factory);
  }

  static DexType createExternalType(
      SyntheticKind kind, DexType context, String id, DexItemFactory factory) {
    return createType(EXTERNAL_SYNTHETIC_CLASS_SEPARATOR, kind, context, id, factory);
  }

  private static DexType createType(
      String separator, SyntheticKind kind, DexType context, String id, DexItemFactory factory) {
    return factory.createType(createDescriptor(separator, kind, context.getInternalName(), id));
  }

  private static String createDescriptor(
      String separator, SyntheticKind kind, String context, String id) {
    return DescriptorUtils.getDescriptorFromClassBinaryName(
        context + separator + kind.descriptor + id);
  }

  public static boolean verifyNotInternalSynthetic(DexType type) {
    return verifyNotInternalSynthetic(type.toDescriptorString());
  }

  public static boolean verifyNotInternalSynthetic(ClassReference reference) {
    return verifyNotInternalSynthetic(reference.getDescriptor());
  }

  public static boolean verifyNotInternalSynthetic(String typeBinaryNameOrDescriptor) {
    assert !typeBinaryNameOrDescriptor.contains(INTERNAL_SYNTHETIC_CLASS_SEPARATOR);
    return true;
  }

  // Visible via package protection in SyntheticItemsTestUtils.

  enum Phase {
    INTERNAL,
    EXTERNAL
  }

  static String getPhaseSeparator(Phase phase) {
    assert phase != null;
    return phase == Phase.INTERNAL
        ? INTERNAL_SYNTHETIC_CLASS_SEPARATOR
        : EXTERNAL_SYNTHETIC_CLASS_SEPARATOR;
  }

  static ClassReference makeSyntheticReferenceForTest(
      ClassReference context, SyntheticKind kind, String id) {
    return Reference.classFromDescriptor(
        createDescriptor(EXTERNAL_SYNTHETIC_CLASS_SEPARATOR, kind, context.getBinaryName(), id));
  }

  static boolean isSynthetic(ClassReference clazz, Phase phase, SyntheticKind kind) {
    String typeName = clazz.getTypeName();
    String separator = getPhaseSeparator(phase);
    int i = typeName.indexOf(separator);
    return i >= 0 && checkMatchFrom(kind, typeName, i, separator, phase == Phase.EXTERNAL);
  }

  private static boolean checkMatchFrom(
      SyntheticKind kind,
      String name,
      int i,
      String externalSyntheticClassSeparator,
      boolean checkIntSuffix) {
    int end = i + externalSyntheticClassSeparator.length() + kind.descriptor.length();
    if (end >= name.length()) {
      return false;
    }
    String prefix = name.substring(i, end);
    return prefix.equals(externalSyntheticClassSeparator + kind.descriptor)
        && (!checkIntSuffix || isInt(name.substring(end)));
  }

  private static boolean isInt(String str) {
    if (str.isEmpty()) {
      return false;
    }
    if ('0' == str.charAt(0)) {
      return str.length() == 1;
    }
    for (int i = 0; i < str.length(); i++) {
      if (!Character.isDigit(str.charAt(i))) {
        return false;
      }
    }
    return true;
  }
}
