// Copyright (c) 2020, 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 static com.android.tools.r8.graph.GenericSignature.EMPTY_SUPER_INTERFACES;
import static com.android.tools.r8.graph.GenericSignature.EMPTY_TYPE_ARGUMENTS;
import static com.android.tools.r8.graph.GenericSignature.EMPTY_TYPE_PARAMS;
import static com.android.tools.r8.graph.GenericSignature.EMPTY_TYPE_SIGNATURES;
import static com.android.tools.r8.graph.GenericSignature.FieldTypeSignature.noSignature;
import static com.android.tools.r8.graph.GenericSignature.StarFieldTypeSignature.STAR_FIELD_TYPE_SIGNATURE;
import static com.google.common.base.Predicates.alwaysFalse;

import com.android.tools.r8.graph.GenericSignature.ArrayTypeSignature;
import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.GenericSignature.ClassTypeSignature;
import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
import com.android.tools.r8.graph.GenericSignature.FormalTypeParameter;
import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
import com.android.tools.r8.graph.GenericSignature.ReturnType;
import com.android.tools.r8.graph.GenericSignature.TypeSignature;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;

public class GenericSignatureTypeRewriter {

  private final DexItemFactory factory;
  private final Predicate<DexType> wasPruned;
  private final Function<DexType, DexType> lookupType;
  private final DexProgramClass context;

  private final FieldTypeSignature objectTypeSignature;

  public GenericSignatureTypeRewriter(AppView<?> appView, DexProgramClass context) {
    this(
        appView.dexItemFactory(),
        appView.appInfo().hasLiveness()
            ? appView.appInfo().withLiveness()::wasPruned
            : alwaysFalse(),
        appView.graphLens()::lookupType,
        context);
  }

  public GenericSignatureTypeRewriter(
      DexItemFactory factory,
      Predicate<DexType> wasPruned,
      Function<DexType, DexType> lookupType,
      DexProgramClass context) {
    this.factory = factory;
    this.wasPruned = wasPruned;
    this.lookupType = lookupType;
    this.context = context;
    objectTypeSignature = new ClassTypeSignature(factory.objectType, EMPTY_TYPE_ARGUMENTS);
  }

  public ClassSignature rewrite(ClassSignature classSignature) {
    if (classSignature.hasNoSignature()) {
      return classSignature;
    }
    return new ClassSignatureRewriter().run(classSignature);
  }

  public FieldTypeSignature rewrite(FieldTypeSignature fieldTypeSignature) {
    if (fieldTypeSignature.hasNoSignature()) {
      return fieldTypeSignature;
    }
    FieldTypeSignature rewrittenSignature = new TypeSignatureRewriter().run(fieldTypeSignature);
    return rewrittenSignature == null ? FieldTypeSignature.noSignature() : rewrittenSignature;
  }

  public MethodTypeSignature rewrite(MethodTypeSignature methodTypeSignature) {
    if (methodTypeSignature.hasNoSignature()) {
      return methodTypeSignature;
    }
    return new MethodTypeSignatureRewriter().run(methodTypeSignature);
  }

  private class ClassSignatureRewriter implements GenericSignatureVisitor {

    private final List<FormalTypeParameter> rewrittenTypeParameters = new ArrayList<>();
    private ClassTypeSignature rewrittenSuperClass;
    private final List<ClassTypeSignature> rewrittenSuperInterfaces = new ArrayList<>();

    @Override
    public void visitClassSignature(ClassSignature classSignature) {
      classSignature.visit(this);
    }

    @Override
    public void visitFormalTypeParameters(List<FormalTypeParameter> formalTypeParameters) {
      for (FormalTypeParameter formalTypeParameter : formalTypeParameters) {
        rewrittenTypeParameters.add(new FormalTypeParameterRewriter().run(formalTypeParameter));
      }
    }

    @Override
    public void visitSuperClass(ClassTypeSignature classTypeSignature) {
      rewrittenSuperClass = new ClassTypeSignatureRewriter(true).run(classTypeSignature);
      if (rewrittenSuperClass == null) {
        rewrittenSuperClass = new ClassTypeSignature(factory.objectType, EMPTY_TYPE_ARGUMENTS);
      }
    }

    @Override
    public void visitSuperInterface(ClassTypeSignature classTypeSignature) {
      ClassTypeSignature superInterface =
          new ClassTypeSignatureRewriter(true).run(classTypeSignature);
      if (superInterface != null) {
        rewrittenSuperInterfaces.add(superInterface);
      }
    }

    private ClassSignature run(ClassSignature classSignature) {
      classSignature.visit(this);
      if (rewrittenTypeParameters.isEmpty()
          && rewrittenSuperInterfaces.isEmpty()
          && rewrittenSuperClass.isNoSignature()
          && rewrittenSuperClass.type == factory.objectType) {
        return ClassSignature.noSignature();
      }
      return new ClassSignature(
          rewrittenTypeParameters.isEmpty() ? EMPTY_TYPE_PARAMS : rewrittenTypeParameters,
          rewrittenSuperClass,
          rewrittenSuperInterfaces.isEmpty() ? EMPTY_SUPER_INTERFACES : rewrittenSuperInterfaces);
    }
  }

  private class MethodTypeSignatureRewriter implements GenericSignatureVisitor {

    private final List<FormalTypeParameter> rewrittenTypeParameters = new ArrayList<>();
    private final List<TypeSignature> rewrittenTypeSignatures = new ArrayList<>();

    ReturnType rewrittenReturnType = null;
    private final List<TypeSignature> rewrittenThrowsSignatures = new ArrayList<>();

    @Override
    public void visitFormalTypeParameters(List<FormalTypeParameter> formalTypeParameters) {
      for (FormalTypeParameter formalTypeParameter : formalTypeParameters) {
        rewrittenTypeParameters.add(new FormalTypeParameterRewriter().run(formalTypeParameter));
      }
    }

    @Override
    public void visitMethodTypeSignatures(List<TypeSignature> typeSignatures) {
      for (TypeSignature typeSignature : typeSignatures) {
        TypeSignature rewrittenType = new TypeSignatureRewriter().run(typeSignature);
        rewrittenTypeSignatures.add(rewrittenType == null ? objectTypeSignature : rewrittenType);
      }
    }

    @Override
    public void visitReturnType(ReturnType returnType) {
      if (returnType.isVoidDescriptor()) {
        rewrittenReturnType = ReturnType.VOID;
      } else {
        TypeSignature originalType = returnType.typeSignature();
        TypeSignature rewrittenType = new TypeSignatureRewriter().run(originalType);
        if (rewrittenType == null) {
          rewrittenReturnType = ReturnType.VOID;
        } else if (rewrittenType == originalType) {
          rewrittenReturnType = returnType;
        } else {
          rewrittenReturnType = new ReturnType(rewrittenType);
        }
      }
    }

    @Override
    public void visitThrowsSignatures(List<TypeSignature> typeSignatures) {
      for (TypeSignature typeSignature : typeSignatures) {
        TypeSignature rewrittenType = new TypeSignatureRewriter().run(typeSignature);
        // If a throwing type is no longer found we remove it from the signature.
        if (rewrittenType != null) {
          rewrittenThrowsSignatures.add(rewrittenType);
        }
      }
    }

    private MethodTypeSignature run(MethodTypeSignature methodTypeSignature) {
      methodTypeSignature.visit(this);
      assert rewrittenReturnType != null;
      if (rewrittenTypeParameters.isEmpty()
          && rewrittenTypeSignatures.isEmpty()
          && rewrittenReturnType.isVoidDescriptor()
          && rewrittenThrowsSignatures.isEmpty()) {
        return MethodTypeSignature.noSignature();
      }
      return new MethodTypeSignature(
          rewrittenTypeParameters.isEmpty() ? EMPTY_TYPE_PARAMS : rewrittenTypeParameters,
          rewrittenTypeSignatures.isEmpty() ? EMPTY_TYPE_SIGNATURES : rewrittenTypeSignatures,
          rewrittenReturnType,
          rewrittenThrowsSignatures.isEmpty() ? EMPTY_TYPE_SIGNATURES : rewrittenThrowsSignatures);
    }
  }

  private class FormalTypeParameterRewriter implements GenericSignatureVisitor {

    private FieldTypeSignature rewrittenClassBound = noSignature();
    private final List<FieldTypeSignature> rewrittenInterfaceBounds = new ArrayList<>();

    @Override
    public void visitClassBound(FieldTypeSignature fieldSignature) {
      rewrittenClassBound = new TypeSignatureRewriter().run(fieldSignature);
    }

    @Override
    public void visitInterfaceBound(FieldTypeSignature fieldSignature) {
      FieldTypeSignature interfaceBound = new TypeSignatureRewriter().run(fieldSignature);
      if (interfaceBound != null) {
        rewrittenInterfaceBounds.add(interfaceBound);
      }
    }

    private FormalTypeParameter run(FormalTypeParameter formalTypeParameter) {
      formalTypeParameter.visit(this);
      // Guard against the case where we have <T::...> that is, no class or interfaces bounds.
      if (rewrittenInterfaceBounds.isEmpty()
          && (rewrittenClassBound == null || !rewrittenClassBound.hasSignature())) {
        rewrittenClassBound = objectTypeSignature;
      }
      return new FormalTypeParameter(
          formalTypeParameter.name,
          rewrittenClassBound == null ? noSignature() : rewrittenClassBound,
          rewrittenInterfaceBounds.isEmpty() ? EMPTY_TYPE_ARGUMENTS : rewrittenInterfaceBounds);
    }
  }

  private class TypeSignatureRewriter implements GenericSignatureVisitor {

    private TypeSignature run(TypeSignature typeSignature) {
      if (typeSignature.isBaseTypeSignature()) {
        return typeSignature;
      }
      assert typeSignature.isFieldTypeSignature();
      return run(typeSignature.asFieldTypeSignature());
    }

    private FieldTypeSignature run(FieldTypeSignature fieldTypeSignature) {
      if (fieldTypeSignature.isStar()) {
        return fieldTypeSignature;
      }
      if (fieldTypeSignature.isTypeVariableSignature()) {
        return fieldTypeSignature;
      }
      if (fieldTypeSignature.isArrayTypeSignature()) {
        ArrayTypeSignature arrayTypeSignature = fieldTypeSignature.asArrayTypeSignature();
        TypeSignature rewrittenElement = run(arrayTypeSignature.elementSignature);
        if (rewrittenElement == null) {
          return new ArrayTypeSignature(objectTypeSignature);
        }
        return rewrittenElement.toArrayTypeSignature();
      }
      assert fieldTypeSignature.isClassTypeSignature();
      ClassTypeSignature classTypeSignature = fieldTypeSignature.asClassTypeSignature();
      if (classTypeSignature.isNoSignature()) {
        return classTypeSignature;
      }
      return new ClassTypeSignatureRewriter(false).run(classTypeSignature);
    }
  }

  private class ClassTypeSignatureRewriter implements GenericSignatureVisitor {

    private final boolean isSuperClassOrInterface;

    // These fields are updated when iterating the modeled structure.
    private DexType currentType;

    // The following references are used to have a head and tail pointer to the classTypeSignature
    // link we are building. The topClassSignature will have a reference to the top-most package
    // and class-name. The parentClassSignature is a pointer pointing to the tail always and will
    // be linked and updated when calling ClassTypeSignature.link.
    private ClassTypeSignature topClassSignature;
    private ClassTypeSignature parentClassSignature;

    private ClassTypeSignatureRewriter(boolean isSuperClassOrInterface) {
      this.isSuperClassOrInterface = isSuperClassOrInterface;
    }

    @Override
    public void visitSimpleClass(ClassTypeSignature classTypeSignature) {
      currentType = getTarget(classTypeSignature.type);
      if (currentType == null) {
        return;
      }
      classTypeSignature.visit(this);
    }

    @Override
    public void visitTypeArguments(List<FieldTypeSignature> typeArguments) {
      ClassTypeSignature newClassTypeSignature;
      if (typeArguments.isEmpty()) {
        newClassTypeSignature = new ClassTypeSignature(currentType, EMPTY_TYPE_ARGUMENTS);
      } else {
        List<FieldTypeSignature> rewrittenTypeArguments = new ArrayList<>(typeArguments.size());
        for (FieldTypeSignature typeArgument : typeArguments) {
          if (typeArgument.isStar()) {
            rewrittenTypeArguments.add(typeArgument);
            continue;
          }
          FieldTypeSignature rewritten = new TypeSignatureRewriter().run(typeArgument);
          if (rewritten != null) {
            rewrittenTypeArguments.add(rewritten.asArgument(typeArgument.getWildcardIndicator()));
          } else {
            rewrittenTypeArguments.add(STAR_FIELD_TYPE_SIGNATURE);
          }
        }
        newClassTypeSignature = new ClassTypeSignature(currentType, rewrittenTypeArguments);
      }
      if (topClassSignature == null) {
        topClassSignature = newClassTypeSignature;
        parentClassSignature = newClassTypeSignature;
      } else {
        ClassTypeSignature.link(parentClassSignature, newClassTypeSignature);
        parentClassSignature = newClassTypeSignature;
      }
    }

    private ClassTypeSignature run(ClassTypeSignature classTypeSignature) {
      currentType = getTarget(classTypeSignature.type);
      if (currentType == null) {
        return null;
      }
      classTypeSignature.visit(this);
      return topClassSignature;
    }

    private DexType getTarget(DexType type) {
      DexType rewrittenType = lookupType.apply(type);
      if (wasPruned.test(rewrittenType)) {
        return null;
      }
      if (isSuperClassOrInterface && context.type == rewrittenType) {
        return null;
      }
      return rewrittenType;
    }
  }
}
