// 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.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexCallSite;
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.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.InnerClassAttribute;
import com.android.tools.r8.utils.InternalOptions;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

// Naming lens for rewriting type prefixes.
public class PrefixRewritingNamingLens extends NamingLens {

  final NamingLens namingLens;
  final InternalOptions options;
  final AppView<?> appView;

  public static NamingLens createPrefixRewritingNamingLens(AppView<?> appView) {
    return createPrefixRewritingNamingLens(appView, NamingLens.getIdentityLens());
  }

  public static NamingLens createPrefixRewritingNamingLens(
      AppView<?> appView, NamingLens namingLens) {
    if (!appView.rewritePrefix.isRewriting()) {
      return namingLens;
    }
    return new PrefixRewritingNamingLens(namingLens, appView);
  }

  public PrefixRewritingNamingLens(NamingLens namingLens, AppView<?> appView) {
    this.appView = appView;
    this.namingLens = namingLens;
    this.options = appView.options();
  }

  private boolean isRenamed(DexType type) {
    return getRenaming(type) != null;
  }

  private DexString getRenaming(DexType type) {
    DexString descriptor = null;
    if (appView.rewritePrefix.hasRewrittenType(type, appView)) {
      descriptor = appView.rewritePrefix.rewrittenType(type, appView).descriptor;
    }
    return descriptor;
  }

  @Override
  public boolean hasPrefixRewritingLogic() {
    return true;
  }

  @Override
  public DexString prefixRewrittenType(DexType type) {
    return getRenaming(type);
  }

  @Override
  public DexString lookupDescriptor(DexType type) {
    DexString renaming = getRenaming(type);
    return renaming != null ? renaming : namingLens.lookupDescriptor(type);
  }

  @Override
  public DexString lookupInnerName(InnerClassAttribute attribute, InternalOptions options) {
    if (isRenamed(attribute.getInner())) {
      // Prefix rewriting does not influence the inner name.
      return attribute.getInnerName();
    }
    return namingLens.lookupInnerName(attribute, options);
  }

  @Override
  public DexString lookupName(DexMethod method) {
    if (isRenamed(method.holder)) {
      // Prefix rewriting does not influence the method name.
      return method.name;
    }
    return namingLens.lookupName(method);
  }

  @Override
  public DexString lookupMethodName(DexCallSite callSite) {
    if (isRenamed(callSite.bootstrapMethod.rewrittenTarget.holder)) {
      // Prefix rewriting does not influence the inner name.
      return callSite.methodName;
    }
    return namingLens.lookupMethodName(callSite);
  }

  @Override
  public DexString lookupName(DexField field) {
    if (isRenamed(field.holder)) {
      // Prefix rewriting does not influence the field name.
      return field.name;
    }
    return namingLens.lookupName(field);
  }

  @Override
  public boolean verifyNoOverlap(Map<DexType, DexString> map) {
    throw new Unreachable("Multiple prefix rewriting lens not supported.");
  }

  @Override
  public String lookupPackageName(String packageName) {
    // Used for resource shrinking.
    // Desugared libraries do not have resources.
    // Hence this call is necessarily for the minifyingLens.
    // TODO(b/134732760): This assertion does not hold with ressources with renamed prefixes.
    // Write a test where the assertion does not hold and fix it.
    assert verifyNotPrefixRewrittenPackage(packageName);
    return namingLens.lookupPackageName(packageName);
  }

  private boolean verifyNotPrefixRewrittenPackage(String packageName) {
    appView.rewritePrefix.forAllRewrittenTypes(
        dexType -> {
          assert !dexType.getPackageDescriptor().equals(packageName);
        });
    return true;
  }

  @Override
  public void forAllRenamedTypes(Consumer<DexType> consumer) {
    // Used for printing the applyMapping map.
    // If compiling the program using a desugared library, nothing needs to be printed.
    // If compiling the desugared library, the mapping needs to be printed.
    // When debugging the program, both mapping files need to be merged.
    if (options.isDesugaredLibraryCompilation()) {
      appView.rewritePrefix.forAllRewrittenTypes(consumer);
    }
    namingLens.forAllRenamedTypes(consumer);
  }

  @Override
  public <T extends DexItem> Map<String, T> getRenamedItems(
      Class<T> clazz, Predicate<T> predicate, Function<T, String> namer) {
    Map<String, T> renamedItemsPrefixRewritting;
    if (clazz == DexType.class) {
      renamedItemsPrefixRewritting = new HashMap<>();
      appView.rewritePrefix.forAllRewrittenTypes(
          item -> {
            T cast = clazz.cast(item);
            if (predicate.test(cast)) {
              renamedItemsPrefixRewritting.put(namer.apply(cast), cast);
            }
          });
    } else {
      renamedItemsPrefixRewritting = Collections.emptyMap();
    }
    Map<String, T> renamedItemsMinifier = namingLens.getRenamedItems(clazz, predicate, namer);
    // The Collector throws an exception for duplicated keys.
    return Stream.concat(
            renamedItemsPrefixRewritting.entrySet().stream(),
            renamedItemsMinifier.entrySet().stream())
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
  }

  @Override
  public boolean checkTargetCanBeTranslated(DexMethod item) {
    return namingLens.checkTargetCanBeTranslated(item);
  }
}
