// Copyright (c) 2019, 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.ir.optimize.info.OptimizationFeedback.getSimpleFeedback;

import com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.NumberGenerator;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.conversion.LensCodeRewriterUtils;
import com.android.tools.r8.ir.conversion.MethodProcessor;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.kotlin.KotlinMethodLevelInfo;
import com.android.tools.r8.logging.Log;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.position.MethodPosition;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.AndroidApiLevel;

/** Type representing a method definition in the programs compilation unit and its holder. */
public final class ProgramMethod extends DexClassAndMethod
    implements ProgramMember<DexEncodedMethod, DexMethod> {

  public ProgramMethod(DexProgramClass holder, DexEncodedMethod method) {
    super(holder, method);
  }

  public IRCode buildIR(AppView<?> appView) {
    DexEncodedMethod method = getDefinition();
    return method.hasCode() ? method.getCode().buildIR(this, appView, getOrigin()) : null;
  }

  public IRCode buildInliningIR(
      ProgramMethod context,
      AppView<?> appView,
      NumberGenerator valueNumberGenerator,
      Position callerPosition,
      Origin origin,
      MethodProcessor methodProcessor) {
    Code code = getDefinition().getCode();
    GraphLens codeLens = appView.graphLens();
    RewrittenPrototypeDescription protoChanges = RewrittenPrototypeDescription.none();
    if (methodProcessor.shouldApplyCodeRewritings(this)) {
      codeLens = appView.codeLens();
      protoChanges = appView.graphLens().lookupPrototypeChangesForMethodDefinition(getReference());
    }
    return code.buildInliningIR(
        context,
        this,
        appView,
        codeLens,
        valueNumberGenerator,
        callerPosition,
        origin,
        protoChanges);
  }

  public void collectIndexedItems(
      IndexedItemCollection indexedItems, GraphLens graphLens, LensCodeRewriterUtils rewriter) {
    DexEncodedMethod definition = getDefinition();
    assert !definition.isObsolete();
    assert !definition.hasCode() || definition.getCode().isDexCode();
    getReference().collectIndexedItems(indexedItems);
    Code code = definition.getCode();
    if (code != null && code.isDexCode()) {
      code.asDexCode().collectIndexedItems(indexedItems, this, graphLens, rewriter);
    }
    definition.annotations().collectIndexedItems(indexedItems);
    definition.parameterAnnotationsList.collectIndexedItems(indexedItems);
  }

  public boolean canBeConvertedToAbstractMethod(AppView<AppInfoWithLiveness> appView) {
    return (appView.options().canUseAbstractMethodOnNonAbstractClass()
            || getHolder().isAbstract()
            || getHolder().isInterface())
        && !getAccessFlags().isNative()
        && !getAccessFlags().isPrivate()
        && !getAccessFlags().isStatic()
        && !appView.appInfo().isFailedResolutionTarget(getReference());
  }

  public void convertToAbstractOrThrowNullMethod(AppView<AppInfoWithLiveness> appView) {
    if (!convertToAbstractMethodIfPossible(appView)) {
      convertToThrowNullMethod(appView);
    }
  }

  private boolean convertToAbstractMethodIfPossible(AppView<AppInfoWithLiveness> appView) {
    boolean canBeAbstract = canBeConvertedToAbstractMethod(appView);
    if (canBeAbstract) {
      MethodAccessFlags accessFlags = getAccessFlags();
      accessFlags.demoteFromFinal();
      accessFlags.demoteFromStrict();
      accessFlags.demoteFromSynchronized();
      accessFlags.promoteToAbstract();
      getDefinition().clearApiLevelForCode(appView);
      getDefinition().unsetCode();
      getSimpleFeedback().unsetOptimizationInfoForAbstractMethod(this);
    }
    return canBeAbstract;
  }

  public void convertToThrowNullMethod(AppView<?> appView) {
    MethodAccessFlags accessFlags = getAccessFlags();
    accessFlags.demoteFromAbstract();
    Code emptyThrowingCode = getDefinition().buildEmptyThrowingCode(appView.options());
    getDefinition().setApiLevelForCode(AndroidApiLevel.minApiLevelIfEnabledOrUnknown(appView));
    getDefinition().setCode(emptyThrowingCode, appView);
    getSimpleFeedback().markProcessed(getDefinition(), ConstraintWithTarget.ALWAYS);
    getSimpleFeedback().unsetOptimizationInfoForThrowNullMethod(this);
  }

  public void registerCodeReferences(UseRegistry<?> registry) {
    Code code = getDefinition().getCode();
    if (code != null) {
      if (Log.ENABLED) {
        Log.verbose(getClass(), "Registering definitions reachable from `%s`.", this);
      }
      code.registerCodeReferences(this, registry);
    }
  }

  public <R> R registerCodeReferencesWithResult(UseRegistryWithResult<R, ?> registry) {
    registerCodeReferences(registry);
    return registry.getResult();
  }

  @Override
  public ProgramMethod getContext() {
    return this;
  }

  @Override
  public DexProgramClass getContextClass() {
    return getHolder();
  }

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

  @Override
  public ProgramMethod asProgramMember() {
    return this;
  }

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

  @Override
  public ProgramMethod asMethod() {
    return this;
  }

  @Override
  public ProgramMethod asProgramMethod() {
    return this;
  }

  @Override
  public DexProgramClass getHolder() {
    DexClass holder = super.getHolder();
    assert holder.isProgramClass();
    return holder.asProgramClass();
  }

  @Override
  public KotlinMethodLevelInfo getKotlinInfo() {
    return getDefinition().getKotlinInfo();
  }

  public MethodPosition getPosition() {
    return getDefinition().getPosition();
  }
}
