// Copyright (c) 2023, 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.graph.fixup;

import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexMethodSignature;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.utils.collections.DexMethodSignatureBiMap;
import com.google.common.collect.BiMap;
import java.util.function.BiConsumer;

public class MethodNamingUtility {

  private final DexItemFactory factory;
  private final DexMethodSignatureBiMap<DexMethodSignature> inheritedSignatures;
  private final BiMap<DexMethod, DexMethod> localSignatures;

  public MethodNamingUtility(
      DexItemFactory factory,
      DexMethodSignatureBiMap<DexMethodSignature> inheritedSignatures,
      BiMap<DexMethod, DexMethod> localSignatures) {
    this.factory = factory;
    this.inheritedSignatures = inheritedSignatures;
    this.localSignatures = localSignatures;
  }

  @SuppressWarnings("ReferenceEquality")
  public DexMethod nextUniqueMethod(
      DexEncodedMethod method, DexProto newProto, DexType initExtraType) {
    DexMethod reference = method.getReference();

    if (method.isClassInitializer()) {
      assert reference.getProto() == newProto;
      return reference;
    }

    if (method.isInstanceInitializer()) {
      assert initExtraType != null;
      return nextUniqueInitializer(reference, newProto, initExtraType);
    }

    if (method.isNonPrivateVirtualMethod()) {
      return nextUniqueVirtualMethod(reference, newProto);
    }

    return nextUniquePrivateOrStaticMethod(reference, newProto);
  }

  @SuppressWarnings("ReferenceEquality")
  private DexMethod nextUniqueInitializer(
      DexMethod reference, DexProto newProto, DexType initExtraType) {
    assert !inheritedSignatures.containsKey(reference.getSignature());

    // 1) We check if the reference has already been reserved (pinning).
    DexMethod remapped = localSignatures.get(reference);
    if (remapped != null) {
      assert remapped.getProto() == newProto;
      return remapped.withHolder(reference.getHolderType(), factory);
    }

    // 2) We check for collision with already mapped methods.
    DexMethod newMethod = reference.withProto(newProto, factory);
    if (localSignatures.containsValue(newMethod)) {
      // This collides with something that has been renamed into this.
      newMethod =
          factory.createInstanceInitializerWithFreshProto(
              newMethod, initExtraType, tryMethod -> !localSignatures.containsValue(tryMethod));
    }

    // 3) Finally register the new method and return it.
    assert !localSignatures.containsValue(newMethod);
    localSignatures.put(reference, newMethod);
    return newMethod;
  }

  private DexMethod nextUniquePrivateOrStaticMethod(DexMethod reference, DexProto newProto) {
    return nextUniqueMethod(reference, newProto, localSignatures::put);
  }

  private DexMethod nextUniqueVirtualMethod(DexMethod reference, DexProto newProto) {
    return nextUniqueMethod(
        reference,
        newProto,
        (from, to) -> inheritedSignatures.put(from.getSignature(), to.getSignature()));
  }

  private boolean anyCollision(DexMethod method) {
    return localSignatures.containsValue(method)
        || inheritedSignatures.containsValue(method.getSignature());
  }

  @SuppressWarnings("ReferenceEquality")
  private DexMethod nextUniqueMethod(
      DexMethod reference, DexProto newProto, BiConsumer<DexMethod, DexMethod> registration) {
    // 1) We check if the reference has already been reserved (pinning or override).
    DexMethodSignature remappedSignature = inheritedSignatures.get(reference.getSignature());
    if (remappedSignature != null) {
      assert remappedSignature.getProto() == newProto;
      return remappedSignature.withHolder(reference.getHolderType(), factory);
    }

    // 2) We check for collision with already mapped methods.
    DexMethod newMethod = reference.withProto(newProto, factory);
    if (anyCollision(newMethod)) {
      newMethod =
          factory.createFreshMethodNameWithoutHolder(
              newMethod.getName().toString(),
              newMethod.getProto(),
              newMethod.getHolderType(),
              tryMethod -> !anyCollision(tryMethod));
    }

    // 3) Finally register the new method and return it.
    assert !anyCollision(newMethod);
    registration.accept(reference, newMethod);
    return newMethod;
  }
}
