// Copyright (c) 2022, 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.optimize.proto;

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.GraphLens.NonIdentityGraphLens;
import com.android.tools.r8.graph.proto.ArgumentInfoCollection;
import com.android.tools.r8.graph.proto.ArgumentPermutation;
import com.android.tools.r8.graph.proto.RewrittenPrototypeDescription;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.collections.BidirectionalOneToOneHashMap;
import com.android.tools.r8.utils.collections.BidirectionalOneToOneMap;
import com.android.tools.r8.utils.collections.MutableBidirectionalOneToOneMap;
import com.google.common.collect.ImmutableList;
import java.util.IdentityHashMap;
import java.util.Map;

public class ProtoNormalizerGraphLens extends NonIdentityGraphLens {

  private final BidirectionalOneToOneMap<DexMethod, DexMethod> newMethodSignatures;
  private final Map<DexMethod, RewrittenPrototypeDescription> prototypeChanges;

  ProtoNormalizerGraphLens(
      AppView<?> appView,
      BidirectionalOneToOneMap<DexMethod, DexMethod> newMethodSignatures,
      Map<DexMethod, RewrittenPrototypeDescription> prototypeChanges) {
    super(appView);
    this.newMethodSignatures = newMethodSignatures;
    this.prototypeChanges = prototypeChanges;
  }

  public static Builder builder(AppView<AppInfoWithLiveness> appView) {
    return new Builder(appView);
  }

  @Override
  public DexType getOriginalType(DexType type) {
    return getPrevious().getOriginalType(type);
  }

  @Override
  public Iterable<DexType> getOriginalTypes(DexType type) {
    return getPrevious().getOriginalTypes(type);
  }

  @Override
  public DexField getOriginalFieldSignature(DexField field) {
    return getPrevious().getOriginalFieldSignature(field);
  }

  @Override
  public DexField getRenamedFieldSignature(DexField originalField, GraphLens applied) {
    if (this == applied) {
      return originalField;
    }
    return getPrevious().getRenamedFieldSignature(originalField);
  }

  @Override
  public DexMethod getRenamedMethodSignature(DexMethod originalMethod, GraphLens applied) {
    if (this == applied) {
      return originalMethod;
    }
    return getNextMethodSignature(getPrevious().getRenamedMethodSignature(originalMethod));
  }

  @Override
  public RewrittenPrototypeDescription lookupPrototypeChangesForMethodDefinition(
      DexMethod method, GraphLens codeLens) {
    if (this == codeLens) {
      return RewrittenPrototypeDescription.none();
    }
    DexMethod previousMethodSignature = getPreviousMethodSignature(method);
    RewrittenPrototypeDescription previousPrototypeChanges =
        getPrevious().lookupPrototypeChangesForMethodDefinition(previousMethodSignature);
    if (previousMethodSignature == method) {
      return previousPrototypeChanges;
    }
    return previousPrototypeChanges.combine(
        prototypeChanges.getOrDefault(method, RewrittenPrototypeDescription.none()));
  }

  @Override
  public boolean isContextFreeForMethods() {
    return getPrevious().isContextFreeForMethods();
  }

  @Override
  protected FieldLookupResult internalDescribeLookupField(FieldLookupResult previous) {
    return previous;
  }

  @Override
  protected MethodLookupResult internalDescribeLookupMethod(
      MethodLookupResult previous, DexMethod context) {
    DexMethod methodSignature = previous.getReference();
    DexMethod newMethodSignature = getNextMethodSignature(methodSignature);
    if (methodSignature == newMethodSignature) {
      return previous;
    }
    assert !previous.hasReboundReference();
    return MethodLookupResult.builder(this)
        .setPrototypeChanges(
            previous
                .getPrototypeChanges()
                .combine(
                    prototypeChanges.getOrDefault(
                        newMethodSignature, RewrittenPrototypeDescription.none())))
        .setReference(newMethodSignature)
        .setType(previous.getType())
        .build();
  }

  @Override
  protected DexType internalDescribeLookupClassType(DexType previous) {
    return previous;
  }

  @Override
  public DexMethod getPreviousMethodSignature(DexMethod method) {
    return newMethodSignatures.getRepresentativeKeyOrDefault(method, method);
  }

  @Override
  public DexMethod getNextMethodSignature(DexMethod method) {
    return newMethodSignatures.getOrDefault(method, method);
  }

  public static class Builder {

    private final AppView<AppInfoWithLiveness> appView;
    private final MutableBidirectionalOneToOneMap<DexMethod, DexMethod> newMethodSignatures =
        new BidirectionalOneToOneHashMap<>();
    private final Map<DexMethod, RewrittenPrototypeDescription> prototypeChanges =
        new IdentityHashMap<>();

    private Builder(AppView<AppInfoWithLiveness> appView) {
      this.appView = appView;
    }

    public RewrittenPrototypeDescription recordNewMethodSignature(
        DexEncodedMethod method, DexMethod newMethodSignature) {
      assert method.getReference() != newMethodSignature;
      newMethodSignatures.put(method.getReference(), newMethodSignature);
      if (!method.getParameters().equals(newMethodSignature.getParameters())) {
        RewrittenPrototypeDescription prototypeChangesForMethod =
            computePrototypeChanges(method, newMethodSignature);
        prototypeChanges.put(newMethodSignature, prototypeChangesForMethod);
        return prototypeChangesForMethod;
      }
      return RewrittenPrototypeDescription.none();
    }

    // TODO(b/195112263): Canonicalize the permutation maps.
    private static RewrittenPrototypeDescription computePrototypeChanges(
        DexEncodedMethod method, DexMethod newMethodSignature) {
      int firstNonReceiverArgumentIndex = method.getFirstNonReceiverArgumentIndex();
      int numberOfArguments = method.getNumberOfArguments();
      ArgumentPermutation.Builder argumentPermutationBuilder =
          ArgumentPermutation.builder(numberOfArguments);
      boolean[] used = new boolean[numberOfArguments];
      for (int argumentIndex = firstNonReceiverArgumentIndex;
          argumentIndex < numberOfArguments;
          argumentIndex++) {
        DexType argumentType = method.getArgumentType(argumentIndex);
        for (int newArgumentIndex = firstNonReceiverArgumentIndex;
            newArgumentIndex < numberOfArguments;
            newArgumentIndex++) {
          DexType newArgumentType =
              newMethodSignature.getArgumentType(
                  newArgumentIndex, method.getAccessFlags().isStatic());
          if (argumentType == newArgumentType && !used[newArgumentIndex]) {
            argumentPermutationBuilder.setNewArgumentIndex(argumentIndex, newArgumentIndex);
            used[newArgumentIndex] = true;
            break;
          }
        }
      }
      ArgumentPermutation argumentPermutation = argumentPermutationBuilder.build();
      assert !argumentPermutation.isDefault();
      ArgumentInfoCollection argumentInfoCollection =
          ArgumentInfoCollection.builder()
              .setArgumentInfosSize(numberOfArguments)
              .setArgumentPermutation(argumentPermutation)
              .build();
      return RewrittenPrototypeDescription.create(ImmutableList.of(), null, argumentInfoCollection);
    }

    public boolean isEmpty() {
      return newMethodSignatures.isEmpty();
    }

    public ProtoNormalizerGraphLens build() {
      return new ProtoNormalizerGraphLens(appView, newMethodSignatures, prototypeChanges);
    }
  }
}
