// 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.GenericSignatureCorrectnessHelper.SignatureEvaluationResult.INVALID_APPLICATION_COUNT;
import static com.android.tools.r8.graph.GenericSignatureCorrectnessHelper.SignatureEvaluationResult.INVALID_INTERFACE_COUNT;
import static com.android.tools.r8.graph.GenericSignatureCorrectnessHelper.SignatureEvaluationResult.INVALID_SUPER_TYPE;
import static com.android.tools.r8.graph.GenericSignatureCorrectnessHelper.SignatureEvaluationResult.INVALID_TYPE_VARIABLE_UNDEFINED;
import static com.android.tools.r8.graph.GenericSignatureCorrectnessHelper.SignatureEvaluationResult.VALID;

import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.GenericSignature.ClassTypeSignature;
import com.android.tools.r8.graph.GenericSignature.DexDefinitionSignature;
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.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

public class GenericSignatureCorrectnessHelper {

  private enum Mode {
    VERIFY,
    MARK_AS_INVALID;

    public boolean doNotVerify() {
      return markAsInvalid();
    }

    public boolean markAsInvalid() {
      return this == MARK_AS_INVALID;
    }
  }

  public enum SignatureEvaluationResult {
    INVALID_SUPER_TYPE,
    INVALID_INTERFACE_COUNT,
    INVALID_APPLICATION_COUNT,
    INVALID_TYPE_VARIABLE_UNDEFINED,
    VALID;

    boolean isValid() {
      return this == VALID;
    }

    boolean isInvalid() {
      return this != VALID;
    }
  }

  private final AppView<?> appView;
  private final Mode mode;

  private GenericSignatureCorrectnessHelper(AppView<?> appView, Mode mode) {
    this.appView = appView;
    this.mode = mode;
  }

  public static GenericSignatureCorrectnessHelper createForInitialCheck(AppView<?> appView) {
    return new GenericSignatureCorrectnessHelper(appView, Mode.MARK_AS_INVALID);
  }

  public static GenericSignatureCorrectnessHelper createForVerification(AppView<?> appView) {
    return new GenericSignatureCorrectnessHelper(appView, Mode.VERIFY);
  }

  public void run() {
    appView.appInfo().classes().forEach(this::evaluateSignaturesForClass);
  }

  public SignatureEvaluationResult evaluateSignaturesForClass(DexProgramClass clazz) {
    GenericSignatureContextEvaluator genericSignatureContextEvaluator =
        new GenericSignatureContextEvaluator(appView, clazz, mode);
    ClassSignature classSignature = clazz.getClassSignature();
    SignatureEvaluationResult result = VALID;
    if (classSignature.hasNoSignature() || !classSignature.isInvalid()) {
      result = genericSignatureContextEvaluator.evaluateClassSignature(classSignature);
      if (result.isInvalid() && mode.markAsInvalid()) {
        clazz.setClassSignature(classSignature.toInvalid());
      }
    }
    for (DexEncodedMethod method : clazz.methods()) {
      SignatureEvaluationResult methodResult =
          evaluate(
              method::getGenericSignature,
              genericSignatureContextEvaluator::visitMethodSignature,
              method::setGenericSignature);
      if (result.isValid() && methodResult.isInvalid()) {
        result = methodResult;
      }
    }
    for (DexEncodedField field : clazz.fields()) {
      SignatureEvaluationResult fieldResult =
          evaluate(
              field::getGenericSignature,
              genericSignatureContextEvaluator::visitFieldTypeSignature,
              field::setGenericSignature);
      if (result.isValid() && fieldResult.isInvalid()) {
        result = fieldResult;
      }
    }
    return result;
  }

  @SuppressWarnings("unchecked")
  private <T extends DexDefinitionSignature<?>> SignatureEvaluationResult evaluate(
      Supplier<T> getter, Function<T, SignatureEvaluationResult> evaluate, Consumer<T> setter) {
    T signature = getter.get();
    if (signature.hasNoSignature() || signature.isInvalid()) {
      // Already marked as invalid, do nothing
      return VALID;
    }
    SignatureEvaluationResult signatureResult = evaluate.apply(signature);
    assert signatureResult.isValid() || mode.doNotVerify();
    if (signatureResult.isInvalid() && mode.doNotVerify()) {
      setter.accept((T) signature.toInvalid());
    }
    return signatureResult;
  }

  private static class GenericSignatureContextEvaluator {

    private final AppView<?> appView;
    private final DexProgramClass context;
    private final Set<String> classFormalTypeParameters = new HashSet<>();
    private final Set<String> methodTypeArguments = new HashSet<>();
    private final Mode mode;

    public GenericSignatureContextEvaluator(
        AppView<?> appView, DexProgramClass context, Mode mode) {
      this.appView = appView;
      this.context = context;
      this.mode = mode;
    }

    private SignatureEvaluationResult evaluateClassSignature(ClassSignature classSignature) {
      classSignature
          .getFormalTypeParameters()
          .forEach(param -> classFormalTypeParameters.add(param.name));
      if (classSignature.hasNoSignature()) {
        return VALID;
      }
      SignatureEvaluationResult signatureEvaluationResult =
          evaluateFormalTypeParameters(classSignature.formalTypeParameters);
      if (signatureEvaluationResult.isInvalid()) {
        return signatureEvaluationResult;
      }
      if ((context.superType != appView.dexItemFactory().objectType
              && context.superType != classSignature.superClassSignature().type())
          || (context.superType == appView.dexItemFactory().objectType
              && classSignature.superClassSignature().hasNoSignature())) {
        assert mode.doNotVerify();
        return INVALID_SUPER_TYPE;
      }
      signatureEvaluationResult =
          evaluateTypeArgumentsAppliedToType(
              classSignature.superClassSignature().typeArguments(), context.superType);
      if (signatureEvaluationResult.isInvalid()) {
        return signatureEvaluationResult;
      }
      List<ClassTypeSignature> superInterfaces = classSignature.superInterfaceSignatures();
      if (context.interfaces.size() != superInterfaces.size()) {
        assert mode.doNotVerify();
        return INVALID_INTERFACE_COUNT;
      }
      DexType[] actualInterfaces = context.interfaces.values;
      for (int i = 0; i < actualInterfaces.length; i++) {
        signatureEvaluationResult =
            evaluateTypeArgumentsAppliedToType(
                superInterfaces.get(i).typeArguments(), actualInterfaces[i]);
        if (signatureEvaluationResult.isInvalid()) {
          return signatureEvaluationResult;
        }
      }
      return VALID;
    }

    private SignatureEvaluationResult visitMethodSignature(MethodTypeSignature methodSignature) {
      methodSignature
          .getFormalTypeParameters()
          .forEach(param -> methodTypeArguments.add(param.name));
      SignatureEvaluationResult evaluateResult =
          evaluateFormalTypeParameters(methodSignature.getFormalTypeParameters());
      if (evaluateResult.isInvalid()) {
        return evaluateResult;
      }
      evaluateResult = evaluateTypeArguments(methodSignature.typeSignatures);
      if (evaluateResult.isInvalid()) {
        return evaluateResult;
      }
      evaluateResult = evaluateTypeArguments(methodSignature.throwsSignatures);
      if (evaluateResult.isInvalid()) {
        return evaluateResult;
      }
      ReturnType returnType = methodSignature.returnType();
      if (!returnType.isVoidDescriptor()) {
        evaluateResult = evaluateTypeArgument(returnType.typeSignature());
        if (evaluateResult.isInvalid()) {
          return evaluateResult;
        }
      }
      methodTypeArguments.clear();
      return evaluateResult;
    }

    private SignatureEvaluationResult evaluateTypeArguments(List<TypeSignature> typeSignatures) {
      for (TypeSignature typeSignature : typeSignatures) {
        SignatureEvaluationResult signatureEvaluationResult = evaluateTypeArgument(typeSignature);
        if (signatureEvaluationResult.isInvalid()) {
          return signatureEvaluationResult;
        }
      }
      return VALID;
    }

    private SignatureEvaluationResult visitFieldTypeSignature(FieldTypeSignature fieldSignature) {
      return evaluateTypeArgument(fieldSignature);
    }

    private SignatureEvaluationResult evaluateFormalTypeParameters(
        List<FormalTypeParameter> typeParameters) {
      for (FormalTypeParameter typeParameter : typeParameters) {
        SignatureEvaluationResult evaluationResult = evaluateTypeParameter(typeParameter);
        if (evaluationResult.isInvalid()) {
          return evaluationResult;
        }
      }
      return VALID;
    }

    private SignatureEvaluationResult evaluateTypeParameter(FormalTypeParameter typeParameter) {
      SignatureEvaluationResult evaluationResult = evaluateTypeArgument(typeParameter.classBound);
      if (evaluationResult.isInvalid()) {
        return evaluationResult;
      }
      if (typeParameter.interfaceBounds != null) {
        for (FieldTypeSignature interfaceBound : typeParameter.interfaceBounds) {
          evaluationResult = evaluateTypeArgument(interfaceBound);
          if (evaluationResult != VALID) {
            return evaluationResult;
          }
        }
      }
      return VALID;
    }

    private SignatureEvaluationResult evaluateTypeArgument(TypeSignature typeSignature) {
      if (typeSignature.isBaseTypeSignature()) {
        return VALID;
      }
      FieldTypeSignature fieldTypeSignature = typeSignature.asFieldTypeSignature();
      if (fieldTypeSignature.hasNoSignature()) {
        return VALID;
      }
      if (fieldTypeSignature.isTypeVariableSignature()) {
        // This is in an applied position, just check that the variable is registered.
        String typeVariable = fieldTypeSignature.asTypeVariableSignature().typeVariable();
        if (classFormalTypeParameters.contains(typeVariable)
            || methodTypeArguments.contains(typeVariable)) {
          return VALID;
        }
        assert mode.doNotVerify();
        return INVALID_TYPE_VARIABLE_UNDEFINED;
      }
      if (fieldTypeSignature.isArrayTypeSignature()) {
        return evaluateTypeArgument(fieldTypeSignature.asArrayTypeSignature().elementSignature());
      }
      assert fieldTypeSignature.isClassTypeSignature();
      return evaluateTypeArguments(fieldTypeSignature.asClassTypeSignature());
    }

    private SignatureEvaluationResult evaluateTypeArguments(ClassTypeSignature classTypeSignature) {
      return evaluateTypeArgumentsAppliedToType(
          classTypeSignature.typeArguments, classTypeSignature.type());
    }

    private SignatureEvaluationResult evaluateTypeArgumentsAppliedToType(
        List<FieldTypeSignature> typeArguments, DexType type) {
      for (FieldTypeSignature typeArgument : typeArguments) {
        SignatureEvaluationResult evaluationResult = evaluateTypeArgument(typeArgument);
        if (evaluationResult.isInvalid()) {
          assert mode.doNotVerify();
          return evaluationResult;
        }
      }
      DexClass clazz = appView.definitionFor(type);
      if (clazz == null) {
        // We do not know if the application of arguments works or not.
        return VALID;
      }
      if (typeArguments.size() != clazz.classSignature.getFormalTypeParameters().size()) {
        assert mode.doNotVerify();
        return INVALID_APPLICATION_COUNT;
      }
      return VALID;
    }
  }
}
