// Copyright (c) 2021, 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;

import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
import com.android.tools.r8.graph.GenericSignature.FormalTypeParameter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;

public class GenericSignatureTypeVariableRemover {

  private final AppView<?> appView;
  private final Predicate<InnerClassAttribute> innerClassPruned;
  private final Predicate<EnclosingMethodAttribute> enclosingClassOrMethodPruned;

  public GenericSignatureTypeVariableRemover(
      AppView<?> appView,
      Predicate<InnerClassAttribute> innerClassPruned,
      Predicate<EnclosingMethodAttribute> enclosingClassOrMethodPruned) {
    this.appView = appView;
    this.innerClassPruned = innerClassPruned;
    this.enclosingClassOrMethodPruned = enclosingClassOrMethodPruned;
  }

  public void removeDeadGenericSignatureTypeVariables(DexProgramClass clazz) {
    if (clazz.getClassSignature().hasNoSignature() || clazz.getClassSignature().isInvalid()) {
      return;
    }
    Map<String, DexType> substitutions = new HashMap<>();
    getPrunedTypeParameters(clazz, substitutions, false);
    if (substitutions.isEmpty()) {
      return;
    }
    GenericSignaturePartialTypeArgumentApplier genericSignatureTypeArgumentApplier =
        GenericSignaturePartialTypeArgumentApplier.build(
            appView, clazz.getClassSignature(), substitutions);
    clazz.setClassSignature(
        genericSignatureTypeArgumentApplier.visitClassSignature(clazz.getClassSignature()));
    clazz
        .methods()
        .forEach(
            method -> {
              if (method.getGenericSignature().hasSignature()
                  && method.getGenericSignature().isValid()
                  && method.isVirtualMethod()) {
                method.setGenericSignature(
                    genericSignatureTypeArgumentApplier.visitMethodSignature(
                        method.getGenericSignature()));
              }
            });
    clazz
        .instanceFields()
        .forEach(
            field -> {
              if (field.getGenericSignature().hasSignature()
                  && field.getGenericSignature().isValid()) {
                field.setGenericSignature(
                    genericSignatureTypeArgumentApplier.visitFieldTypeSignature(
                        field.getGenericSignature()));
              }
            });
  }

  private void getPrunedTypeParameters(
      DexClass clazz, Map<String, DexType> substitutions, boolean seenPruned) {
    InnerClassAttribute innerClassAttribute = clazz.getInnerClassAttributeForThisClass();
    if (innerClassAttribute != null
        && innerClassAttribute.getOuter() != null
        && (seenPruned || innerClassPruned.test(innerClassAttribute))) {
      DexClass outerClass = appView.definitionFor(innerClassAttribute.getOuter());
      if (outerClass != null && outerClass.getClassSignature().isValid()) {
        updateMap(outerClass.getClassSignature().getFormalTypeParameters(), substitutions);
        getPrunedTypeParameters(outerClass, substitutions, true);
      }
    }
    if (clazz.getEnclosingMethodAttribute() != null
        && (seenPruned || enclosingClassOrMethodPruned.test(clazz.getEnclosingMethodAttribute()))) {
      DexClass outerClass =
          appView.definitionFor(clazz.getEnclosingMethodAttribute().getEnclosingType());
      if (outerClass == null) {
        return;
      }
      if (clazz.getEnclosingMethodAttribute().getEnclosingMethod() != null) {
        DexEncodedMethod enclosingMethod =
            outerClass.lookupMethod(clazz.getEnclosingMethodAttribute().getEnclosingMethod());
        if (enclosingMethod != null) {
          updateMap(enclosingMethod.getGenericSignature().getFormalTypeParameters(), substitutions);
          if (enclosingMethod.isStatic()) {
            return;
          }
        }
      }
      if (outerClass.getClassSignature().isValid()) {
        updateMap(outerClass.getClassSignature().getFormalTypeParameters(), substitutions);
      }
      getPrunedTypeParameters(outerClass, substitutions, true);
    }
  }

  private void updateMap(
      List<FormalTypeParameter> formalTypeParameters, Map<String, DexType> substitutions) {
    // We are updating the map going from inner most to outer, thus the any overriding formal type
    // parameters will be in the substitution map already.
    formalTypeParameters.forEach(
        parameter -> {
          if (substitutions.containsKey(parameter.getName())) {
            return;
          }
          // The null substitution will use the wildcard as argument, which is smaller than using
          // Ljava/lang/Object;
          DexType substitution = null;
          FieldTypeSignature classBound = parameter.getClassBound();
          if (classBound != null
              && classBound.hasSignature()
              && classBound.isClassTypeSignature()) {
            substitution = classBound.asClassTypeSignature().type();
          }
          substitutions.put(parameter.getName(), substitution);
        });
  }
}
