// 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.ir.optimize.info;

import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.inlining.SimpleInliningConstraint;
import com.android.tools.r8.ir.analysis.type.DynamicType;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.code.InvokeDirect;
import com.android.tools.r8.ir.code.InvokeMethod;
import com.android.tools.r8.ir.optimize.classinliner.constraint.ClassInlinerMethodConstraint;
import com.android.tools.r8.ir.optimize.enums.classification.EnumUnboxerMethodClassification;
import com.android.tools.r8.ir.optimize.info.bridge.BridgeInfo;
import com.android.tools.r8.ir.optimize.info.initializer.InstanceInitializerInfo;
import com.android.tools.r8.optimize.argumentpropagation.codescanner.AbstractFunction;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.OptionalBool;
import java.util.BitSet;
import java.util.Set;
import java.util.function.Consumer;

public class MethodResolutionOptimizationInfo extends MethodOptimizationInfo {

  private final AbstractValue abstractReturnValue;
  private final DynamicType dynamicReturnType;
  private final boolean mayHaveSideEffects;
  private final boolean neverReturnsNormally;
  private final BitSet nonNullParamOnNormalExits;
  private final BitSet nonNullParamOrThrow;
  private final int returnedArgument;
  private final boolean returnValueOnlyDependsOnArguments;

  MethodResolutionOptimizationInfo(
      AbstractValue abstractReturnValue,
      DynamicType dynamicReturnType,
      boolean mayHaveSideEffects,
      boolean neverReturnsNormally,
      BitSet nonNullParamOnNormalExits,
      BitSet nonNullParamOrThrow,
      int returnedArgument,
      boolean returnValueOnlyDependsOnArguments) {
    this.abstractReturnValue = abstractReturnValue;
    this.dynamicReturnType = dynamicReturnType;
    this.mayHaveSideEffects = mayHaveSideEffects;
    this.neverReturnsNormally = neverReturnsNormally;
    this.nonNullParamOnNormalExits = nonNullParamOnNormalExits;
    this.nonNullParamOrThrow = nonNullParamOrThrow;
    this.returnedArgument = returnedArgument;
    this.returnValueOnlyDependsOnArguments = returnValueOnlyDependsOnArguments;
  }

  static Builder builder() {
    return new Builder();
  }

  static MethodOptimizationInfo create(MethodOptimizationInfo optimizationInfo) {
    return builder()
        .setAbstractReturnValue(optimizationInfo.getAbstractReturnValue())
        .setDynamicReturnType(optimizationInfo.getDynamicType())
        .setMayHaveSideEffects(optimizationInfo.mayHaveSideEffects())
        .setNeverReturnsNormally(optimizationInfo.neverReturnsNormally())
        .setNonNullParamOnNormalExits(optimizationInfo.getNonNullParamOnNormalExits())
        .setNonNullParamOrThrow(optimizationInfo.getNonNullParamOrThrow())
        .applyIf(
            optimizationInfo.returnsArgument(),
            builder -> builder.setReturnedArgument(optimizationInfo.getReturnedArgument()))
        .setReturnValueOnlyDependsOnArguments(optimizationInfo.returnValueOnlyDependsOnArguments())
        .build();
  }

  @Override
  public boolean isMethodResolutionOptimizationInfo() {
    return true;
  }

  @Override
  public AbstractFunction getAbstractFunction() {
    return AbstractFunction.unknown();
  }

  @Override
  public AbstractValue getAbstractReturnValue() {
    return abstractReturnValue;
  }

  @Override
  public DynamicType getDynamicType() {
    return dynamicReturnType;
  }

  @Override
  public boolean mayHaveSideEffects() {
    return mayHaveSideEffects;
  }

  @Override
  public boolean mayHaveSideEffects(InvokeMethod invoke, InternalOptions options) {
    return mayHaveSideEffects;
  }

  @Override
  public boolean neverReturnsNormally() {
    return neverReturnsNormally;
  }

  @Override
  public BitSet getNonNullParamOnNormalExits() {
    return nonNullParamOnNormalExits;
  }

  @Override
  public BitSet getNonNullParamOrThrow() {
    return nonNullParamOrThrow;
  }

  @Override
  public boolean returnsArgument() {
    return returnedArgument >= 0;
  }

  @Override
  public int getReturnedArgument() {
    return returnedArgument;
  }

  @Override
  public boolean returnValueOnlyDependsOnArguments() {
    return returnValueOnlyDependsOnArguments;
  }

  @Override
  public boolean hasBeenInlinedIntoSingleCallSite() {
    throw new Unreachable();
  }

  @Override
  public MutableMethodOptimizationInfo toMutableOptimizationInfo() {
    throw new Unreachable();
  }

  @Override
  public boolean cannotBeKept() {
    throw new Unreachable();
  }

  @Override
  public boolean classInitializerMayBePostponed() {
    throw new Unreachable();
  }

  @Override
  public CallSiteOptimizationInfo getArgumentInfos() {
    throw new Unreachable();
  }

  @Override
  public ClassInlinerMethodConstraint getClassInlinerMethodConstraint() {
    throw new Unreachable();
  }

  @Override
  public EnumUnboxerMethodClassification getEnumUnboxerMethodClassification() {
    throw new Unreachable();
  }

  @Override
  public int getMaxRemovedAndroidLogLevel() {
    throw new Unreachable();
  }

  @Override
  public BridgeInfo getBridgeInfo() {
    throw new Unreachable();
  }

  @Override
  public Set<DexType> getInitializedClassesOnNormalExit() {
    throw new Unreachable();
  }

  @Override
  public InstanceInitializerInfo getContextInsensitiveInstanceInitializerInfo() {
    throw new Unreachable();
  }

  @Override
  public InstanceInitializerInfo getInstanceInitializerInfo(InvokeDirect invoke) {
    throw new Unreachable();
  }

  @Override
  public boolean isConvertCheckNotNull() {
    throw new Unreachable();
  }

  @Override
  public boolean isInitializerEnablingJavaVmAssertions() {
    throw new Unreachable();
  }

  @Override
  public SimpleInliningConstraint getNopInliningConstraint() {
    throw new Unreachable();
  }

  @Override
  public SimpleInliningConstraint getSimpleInliningConstraint() {
    throw new Unreachable();
  }

  @Override
  public boolean hasParametersWithBitwiseOperations() {
    throw new Unreachable();
  }

  @Override
  public BitSet getParametersWithBitwiseOperations() {
    throw new Unreachable();
  }

  @Override
  public BitSet getUnusedArguments() {
    throw new Unreachable();
  }

  @Override
  public boolean isMultiCallerMethod() {
    throw new Unreachable();
  }

  @Override
  public OptionalBool isReturnValueUsed() {
    throw new Unreachable();
  }

  @Override
  public boolean forceInline() {
    throw new Unreachable();
  }

  @Override
  public boolean returnValueHasBeenPropagated() {
    throw new Unreachable();
  }

  static class Builder {

    private AbstractValue abstractReturnValue = AbstractValue.unknown();
    private DynamicType dynamicReturnType = DynamicType.unknown();
    private boolean mayHaveSideEffects = true;
    private boolean neverReturnsNormally = false;
    private BitSet nonNullParamOnNormalExits = null;
    private BitSet nonNullParamOrThrow = null;
    private int returnedArgument = -1;
    private boolean returnValueOnlyDependsOnArguments = false;

    Builder applyIf(boolean condition, Consumer<Builder> fn) {
      if (condition) {
        fn.accept(this);
      }
      return this;
    }

    boolean isEffectivelyDefault() {
      return dynamicReturnType.isUnknown()
          && abstractReturnValue.isUnknown()
          && returnedArgument < 0
          && nonNullParamOnNormalExits == null
          && nonNullParamOrThrow == null
          && mayHaveSideEffects
          && !neverReturnsNormally
          && !returnValueOnlyDependsOnArguments;
    }

    Builder setAbstractReturnValue(AbstractValue abstractReturnValue) {
      this.abstractReturnValue = abstractReturnValue;
      return this;
    }

    Builder setDynamicReturnType(DynamicType dynamicReturnType) {
      this.dynamicReturnType = dynamicReturnType;
      return this;
    }

    Builder setMayHaveSideEffects(boolean mayHaveSideEffects) {
      this.mayHaveSideEffects = mayHaveSideEffects;
      return this;
    }

    Builder setNeverReturnsNormally(boolean neverReturnsNormally) {
      this.neverReturnsNormally = neverReturnsNormally;
      return this;
    }

    Builder setNonNullParamOnNormalExits(BitSet nonNullParamOnNormalExits) {
      this.nonNullParamOnNormalExits = nonNullParamOnNormalExits;
      return this;
    }

    Builder setNonNullParamOrThrow(BitSet nonNullParamOrThrow) {
      this.nonNullParamOrThrow = nonNullParamOrThrow;
      return this;
    }

    Builder setReturnedArgument(int returnedArgument) {
      this.returnedArgument = returnedArgument;
      return this;
    }

    Builder setReturnValueOnlyDependsOnArguments(boolean returnValueOnlyDependsOnArguments) {
      this.returnValueOnlyDependsOnArguments = returnValueOnlyDependsOnArguments;
      return this;
    }

    MethodOptimizationInfo build() {
      if (isEffectivelyDefault()) {
        return DefaultMethodOptimizationInfo.getInstance();
      }
      return new MethodResolutionOptimizationInfo(
          abstractReturnValue,
          dynamicReturnType,
          mayHaveSideEffects,
          neverReturnsNormally,
          nonNullParamOnNormalExits,
          nonNullParamOrThrow,
          returnedArgument,
          returnValueOnlyDependsOnArguments);
    }
  }
}
