// 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.naming;

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItem;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.InnerClassAttribute;
import com.android.tools.r8.naming.ClassNameMinifier.ClassRenaming;
import com.android.tools.r8.naming.FieldNameMinifier.FieldRenaming;
import com.android.tools.r8.naming.MethodNameMinifier.MethodRenaming;
import com.android.tools.r8.optimize.MemberRebindingAnalysis;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.google.common.collect.ImmutableMap;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

class MinifiedRenaming extends NamingLens {

  private final AppView<?> appView;
  private final Map<String, String> packageRenaming;
  private final Map<DexItem, DexString> renaming = new IdentityHashMap<>();

  MinifiedRenaming(
      AppView<?> appView,
      ClassRenaming classRenaming,
      MethodRenaming methodRenaming,
      FieldRenaming fieldRenaming) {
    this.appView = appView;
    this.packageRenaming = classRenaming.packageRenaming;
    renaming.putAll(classRenaming.classRenaming);
    renaming.putAll(methodRenaming.renaming);
    renaming.putAll(methodRenaming.callSiteRenaming);
    renaming.putAll(fieldRenaming.renaming);
  }

  @Override
  public String lookupPackageName(String packageName) {
    return packageRenaming.getOrDefault(packageName, packageName);
  }

  @Override
  public DexString lookupDescriptor(DexType type) {
    return renaming.getOrDefault(type, type.descriptor);
  }

  @Override
  public DexString lookupInnerName(InnerClassAttribute attribute, InternalOptions options) {
    if (attribute.getInnerName() == null) {
      return null;
    }
    DexType innerType = attribute.getInner();
    String inner = DescriptorUtils.descriptorToInternalName(innerType.descriptor.toString());
    // At this point we assume the input was of the form: <OuterType>$<index><InnerName>
    // Find the mapped type and if it remains the same return that, otherwise split at
    // either the input separator ($, $$, or anything that starts with $) or $ (that we recover
    // while minifying, e.g., empty separator, under bar, etc.).
    String innerTypeMapped =
        DescriptorUtils.descriptorToInternalName(lookupDescriptor(innerType).toString());
    if (inner.equals(innerTypeMapped)) {
      return attribute.getInnerName();
    }
    String separator = DescriptorUtils.computeInnerClassSeparator(
        attribute.getOuter(), innerType, attribute.getInnerName());
    if (separator == null) {
      separator = String.valueOf(DescriptorUtils.INNER_CLASS_SEPARATOR);
    }
    int index = innerTypeMapped.lastIndexOf(separator);
    if (index < 0) {
      assert false : innerType + " -> " + innerTypeMapped;
      String descriptor = lookupDescriptor(innerType).toString();
      return options.itemFactory.createString(
          DescriptorUtils.getUnqualifiedClassNameFromDescriptor(descriptor));
    }
    return options.itemFactory.createString(innerTypeMapped.substring(index + separator.length()));
  }

  @Override
  public DexString lookupName(DexMethod method) {
    return renaming.getOrDefault(method, method.name);
  }

  @Override
  public DexString lookupMethodName(DexCallSite callSite) {
    return renaming.getOrDefault(callSite, callSite.methodName);
  }

  @Override
  public DexString lookupName(DexField field) {
    return renaming.getOrDefault(field, field.name);
  }

  @Override
  void forAllRenamedTypes(Consumer<DexType> consumer) {
    DexReference.filterDexType(DexReference.filterDexReference(renaming.keySet().stream()))
        .forEach(consumer);
  }

  @Override
  <T extends DexItem> Map<String, T> getRenamedItems(
      Class<T> clazz, Predicate<T> predicate, Function<T, String> namer) {
    return renaming.keySet().stream()
        .filter(item -> (clazz.isInstance(item) && predicate.test(clazz.cast(item))))
        .map(clazz::cast)
        .collect(ImmutableMap.toImmutableMap(namer, i -> i));
  }

  /**
   * Checks whether the target is precise enough to be translated,
   *
   * <p>We only track the renaming of actual definitions, Thus, if we encounter a method id that
   * does not directly point at a definition, we won't find the actual renaming. To avoid
   * dispatching on every lookup, we assume that the tree has been fully dispatched by {@link
   * MemberRebindingAnalysis}.
   *
   * <p>Library methods are excluded from this check, as those are never renamed.
   */
  @Override
  public boolean checkTargetCanBeTranslated(DexMethod item) {
    if (item.holder.isArrayType()) {
      // Array methods are never renamed, so do not bother to check.
      return true;
    }
    DexClass holder = appView.definitionFor(item.holder);
    if (holder == null || holder.isNotProgramClass()) {
      return true;
    }
    // We don't know which invoke type this method is used for, so checks that it has been
    // rebound either way.
    DexEncodedMethod staticTarget = appView.appInfo().lookupStaticTarget(item);
    DexEncodedMethod directTarget = appView.appInfo().lookupDirectTarget(item);
    DexEncodedMethod virtualTarget = appView.appInfo().lookupVirtualTarget(item.holder, item);
    DexClass staticTargetHolder =
        staticTarget != null ? appView.definitionFor(staticTarget.method.holder) : null;
    DexClass directTargetHolder =
        directTarget != null ? appView.definitionFor(directTarget.method.holder) : null;
    DexClass virtualTargetHolder =
        virtualTarget != null ? appView.definitionFor(virtualTarget.method.holder) : null;
    return (directTarget == null && staticTarget == null && virtualTarget == null)
        || (virtualTarget != null && virtualTarget.method == item)
        || (directTarget != null && directTarget.method == item)
        || (staticTarget != null && staticTarget.method == item)
        || (directTargetHolder != null && directTargetHolder.isNotProgramClass())
        || (virtualTargetHolder != null && virtualTargetHolder.isNotProgramClass())
        || (staticTargetHolder != null && staticTargetHolder.isNotProgramClass())
        || appView.unneededVisibilityBridgeMethods().contains(item);
  }

  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder();
    renaming.forEach(
        (item, str) -> {
          if (item instanceof DexType) {
            builder.append("[c] ");
          } else if (item instanceof DexMethod) {
            builder.append("[m] ");
          } else if (item instanceof DexField) {
            builder.append("[f] ");
          }
          builder.append(item.toSourceString());
          builder.append(" -> ");
          builder.append(str.toSourceString());
          builder.append('\n');
        });
    return builder.toString();
  }
}
