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

import com.android.tools.r8.graph.AppInfo;
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.shaking.Enqueuer.AppInfoWithLiveness;
import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.ImmutableMap;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

public class Minifier {

  private final AppView<AppInfoWithLiveness> appView;
  private final AppInfoWithLiveness appInfo;
  private final RootSet rootSet;
  private final Set<DexCallSite> desugaredCallSites;
  private final InternalOptions options;

  public Minifier(
      AppView<AppInfoWithLiveness> appView,
      RootSet rootSet,
      Set<DexCallSite> desugaredCallSites) {
    this.appView = appView;
    this.appInfo = appView.appInfo();
    this.rootSet = rootSet;
    this.desugaredCallSites = desugaredCallSites;
    this.options = appView.options();
  }

  public NamingLens run(Timing timing) {
    assert options.enableMinification;
    timing.begin("MinifyClasses");
    ClassNameMinifier classNameMinifier = new ClassNameMinifier(appView, rootSet);
    ClassRenaming classRenaming = classNameMinifier.computeRenaming(timing);
    timing.end();

    assert new MinifiedRenaming(
            classRenaming, MethodRenaming.empty(), FieldRenaming.empty(), appInfo)
        .verifyNoCollisions(appInfo.classes(), appInfo.dexItemFactory);

    timing.begin("MinifyMethods");
    MethodRenaming methodRenaming =
        new MethodNameMinifier(appView, rootSet).computeRenaming(desugaredCallSites, timing);
    timing.end();

    assert new MinifiedRenaming(classRenaming, methodRenaming, FieldRenaming.empty(), appInfo)
        .verifyNoCollisions(appInfo.classes(), appInfo.dexItemFactory);

    timing.begin("MinifyFields");
    FieldRenaming fieldRenaming = new FieldNameMinifier(appView, rootSet).computeRenaming(timing);
    timing.end();

    NamingLens lens = new MinifiedRenaming(classRenaming, methodRenaming, fieldRenaming, appInfo);
    assert lens.verifyNoCollisions(appInfo.classes(), appInfo.dexItemFactory);

    timing.begin("MinifyIdentifiers");
    new IdentifierMinifier(
        appInfo, options.getProguardConfiguration().getAdaptClassStrings(), lens).run();
    timing.end();
    return lens;
  }

  private static class MinifiedRenaming extends NamingLens {

    private final AppInfo appInfo;
    private final Map<String, String> packageRenaming;
    private final Map<DexItem, DexString> renaming = new IdentityHashMap<>();

    private MinifiedRenaming(
        ClassRenaming classRenaming,
        MethodRenaming methodRenaming,
        FieldRenaming fieldRenaming,
        AppInfo appInfo) {
      this.appInfo = appInfo;
      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;
      }
      // The Java reflection library assumes that that inner-class names are separated by a $ and
      // thus we allow the mapping of an inner name to rely on that too. If the dollar is not
      // present after pulling off the original inner-name, then we revert to using the simple name
      // of the inner class as its name.
      DexType innerType = attribute.getInner();
      String inner = DescriptorUtils.descriptorToInternalName(innerType.descriptor.toString());
      String innerName = attribute.getInnerName().toString();
      int lengthOfPrefix = inner.length() - innerName.length();
      if (lengthOfPrefix < 0
          || inner.lastIndexOf(DescriptorUtils.INNER_CLASS_SEPARATOR, lengthOfPrefix - 1) < 0
          || !inner.endsWith(innerName)) {
        return lookupSimpleName(innerType, options.itemFactory);
      }

      // 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 $.
      String innerTypeMapped =
          DescriptorUtils.descriptorToInternalName(lookupDescriptor(innerType).toString());
      if (inner.equals(innerTypeMapped)) {
        return attribute.getInnerName();
      }
      int index = innerTypeMapped.lastIndexOf(DescriptorUtils.INNER_CLASS_SEPARATOR);
      if (index < 0) {
        // TODO(b/120639028): Replace this by "assert false" and remove the testing option.
        // Hitting means we have converted a proper Outer$Inner relationship to an invalid one.
        assert !options.testing.allowFailureOnInnerClassErrors
            : "Outer$Inner class was remapped without keeping the dollar separator";
        return lookupSimpleName(innerType, options.itemFactory);
      }
      return options.itemFactory.createString(innerTypeMapped.substring(index + 1));
    }

    @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 = appInfo.definitionFor(item.holder);
      if (holder == null || holder.isLibraryClass()) {
        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 = appInfo.lookupStaticTarget(item);
      DexEncodedMethod directTarget = appInfo.lookupDirectTarget(item);
      DexEncodedMethod virtualTarget = appInfo.lookupVirtualTarget(item.holder, item);
      DexClass staticTargetHolder =
          staticTarget != null ? appInfo.definitionFor(staticTarget.method.getHolder()) : null;
      DexClass directTargetHolder =
          directTarget != null ? appInfo.definitionFor(directTarget.method.getHolder()) : null;
      DexClass virtualTargetHolder =
          virtualTarget != null ? appInfo.definitionFor(virtualTarget.method.getHolder()) : 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.isLibraryClass())
          || (virtualTargetHolder != null && virtualTargetHolder.isLibraryClass())
          || (staticTargetHolder != null && staticTargetHolder.isLibraryClass());
    }

    @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();
    }
  }
}
