// Copyright (c) 2018, 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.lambda;

import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.CheckCast;
import com.android.tools.r8.ir.code.ConstClass;
import com.android.tools.r8.ir.code.ConstMethodHandle;
import com.android.tools.r8.ir.code.ConstMethodType;
import com.android.tools.r8.ir.code.DefaultInstructionVisitor;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.InitClass;
import com.android.tools.r8.ir.code.InstanceGet;
import com.android.tools.r8.ir.code.InstancePut;
import com.android.tools.r8.ir.code.InstructionListIterator;
import com.android.tools.r8.ir.code.Invoke;
import com.android.tools.r8.ir.code.InvokeMethod;
import com.android.tools.r8.ir.code.NewArrayEmpty;
import com.android.tools.r8.ir.code.NewInstance;
import com.android.tools.r8.ir.code.StaticGet;
import com.android.tools.r8.ir.code.StaticPut;
import com.android.tools.r8.ir.optimize.lambda.LambdaMerger.ApplyStrategy;
import com.android.tools.r8.kotlin.Kotlin;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.ListIterator;
import java.util.function.Function;

// Performs processing of the method code (all methods) needed by lambda rewriter.
//
// Functionality can be modified by strategy (specific to lambda group) and lambda
// type visitor.
//
// In general it is used to
//   (a) track the code for illegal lambda type usages inside the code, and
//   (b) patching valid lambda type references to point to lambda group classes instead.
//
// This class is also used inside particular strategies as a context of the instruction
// being checked or patched, it provides access to code, block and instruction iterators.
public abstract class CodeProcessor extends DefaultInstructionVisitor<Void> {
  // Strategy (specific to lambda group) for detecting valid references to the
  // lambda classes (of this group) and patching them with group class references.
  public interface Strategy {
    LambdaGroup group();

    boolean isValidStaticFieldWrite(CodeProcessor context, DexField field);

    boolean isValidStaticFieldRead(CodeProcessor context, DexField field);

    boolean isValidInstanceFieldWrite(CodeProcessor context, DexField field);

    boolean isValidInstanceFieldRead(CodeProcessor context, DexField field);

    boolean isValidInvoke(CodeProcessor context, InvokeMethod invoke);

    boolean isValidNewInstance(CodeProcessor context, NewInstance invoke);

    boolean isValidInitClass(CodeProcessor context, DexType clazz);

    void patch(ApplyStrategy context, NewInstance newInstance);

    void patch(ApplyStrategy context, InvokeMethod invoke);

    void patch(ApplyStrategy context, InstanceGet instanceGet);

    void patch(ApplyStrategy context, StaticGet staticGet);

    void patch(ApplyStrategy context, InitClass initClass);
  }

  // No-op strategy.
  static final Strategy NoOp =
      new Strategy() {
        @Override
        public LambdaGroup group() {
          return null;
        }

        @Override
        public boolean isValidInstanceFieldWrite(CodeProcessor context, DexField field) {
          return false;
        }

        @Override
        public boolean isValidInstanceFieldRead(CodeProcessor context, DexField field) {
          return false;
        }

        @Override
        public boolean isValidStaticFieldWrite(CodeProcessor context, DexField field) {
          return false;
        }

        @Override
        public boolean isValidStaticFieldRead(CodeProcessor context, DexField field) {
          return false;
        }

        @Override
        public boolean isValidInvoke(CodeProcessor context, InvokeMethod invoke) {
          return false;
        }

        @Override
        public boolean isValidNewInstance(CodeProcessor context, NewInstance invoke) {
          return false;
        }

        @Override
        public boolean isValidInitClass(CodeProcessor context, DexType clazz) {
          return false;
        }

        @Override
        public void patch(ApplyStrategy context, NewInstance newInstance) {
          throw new Unreachable();
        }

        @Override
        public void patch(ApplyStrategy context, InvokeMethod invoke) {
          throw new Unreachable();
        }

        @Override
        public void patch(ApplyStrategy context, InstanceGet instanceGet) {
          throw new Unreachable();
        }

        @Override
        public void patch(ApplyStrategy context, StaticGet staticGet) {
          throw new Unreachable();
        }

        @Override
        public void patch(ApplyStrategy context, InitClass initClass) {
          throw new Unreachable();
        }
      };

  public final AppView<AppInfoWithLiveness> appView;
  public final DexItemFactory factory;
  public final Kotlin kotlin;

  // Defines a factory providing a strategy for a lambda type, returns
  // NoOp strategy if the type is not a lambda.
  private final Function<DexType, Strategy> strategyProvider;

  // Visitor for lambda type references seen in unexpected places. Either
  // invalidates the lambda or asserts depending on the processing phase.
  private final LambdaTypeVisitor lambdaChecker;

  // Specify the context of the current instruction: method/code/blocks/instructions.
  public final DexEncodedMethod method;
  public final IRCode code;
  public final ListIterator<BasicBlock> blocks;
  private InstructionListIterator instructions;

  // The inlining context (caller), if any.
  private final DexEncodedMethod context;

  CodeProcessor(
      AppView<AppInfoWithLiveness> appView,
      Function<DexType, Strategy> strategyProvider,
      LambdaTypeVisitor lambdaChecker,
      DexEncodedMethod method,
      IRCode code) {
    this(appView, strategyProvider, lambdaChecker, method, code, null);
  }

  CodeProcessor(
      AppView<AppInfoWithLiveness> appView,
      Function<DexType, Strategy> strategyProvider,
      LambdaTypeVisitor lambdaChecker,
      DexEncodedMethod method,
      IRCode code,
      DexEncodedMethod context) {
    this.appView = appView;
    this.strategyProvider = strategyProvider;
    this.factory = appView.dexItemFactory();
    this.kotlin = factory.kotlin;
    this.lambdaChecker = lambdaChecker;
    this.method = method;
    this.code = code;
    this.blocks = code.listIterator();
    this.context = context;
  }

  public final InstructionListIterator instructions() {
    assert instructions != null;
    return instructions;
  }

  void processCode() {
    while (blocks.hasNext()) {
      BasicBlock block = blocks.next();
      instructions = block.listIterator(code);
      while (instructions.hasNext()) {
        instructions.next().accept(this);
      }
    }
  }

  private boolean shouldRewrite(DexField field) {
    return shouldRewrite(field.holder);
  }

  private boolean shouldRewrite(DexMethod method) {
    return shouldRewrite(method.holder);
  }

  private boolean shouldRewrite(DexType type) {
    // Rewrite references to lambda classes if we are outside the class.
    return type != (context != null ? context : method).holder();
  }

  @Override
  public Void handleInvoke(Invoke invoke) {
    if (invoke.isInvokeNewArray()) {
      lambdaChecker.accept(invoke.asInvokeNewArray().getReturnType());
      return null;
    }
    if (invoke.isInvokeMultiNewArray()) {
      lambdaChecker.accept(invoke.asInvokeMultiNewArray().getReturnType());
      return null;
    }
    if (invoke.isInvokeCustom()) {
      lambdaChecker.accept(invoke.asInvokeCustom().getCallSite());
      return null;
    }

    InvokeMethod invokeMethod = invoke.asInvokeMethod();
    Strategy strategy = strategyProvider.apply(invokeMethod.getInvokedMethod().holder);
    if (strategy.isValidInvoke(this, invokeMethod)) {
      // Invalidate signature, there still should not be lambda references.
      lambdaChecker.accept(invokeMethod.getInvokedMethod().proto);
      // Only rewrite references to lambda classes if we are outside the class.
      if (shouldRewrite(invokeMethod.getInvokedMethod())) {
        process(strategy, invokeMethod);
      }
      return null;
    }

    // For the rest invalidate any references.
    if (invoke.isInvokePolymorphic()) {
      lambdaChecker.accept(invoke.asInvokePolymorphic().getProto());
    }
    lambdaChecker.accept(invokeMethod.getInvokedMethod(), null);
    return null;
  }

  @Override
  public Void visit(NewInstance newInstance) {
    Strategy strategy = strategyProvider.apply(newInstance.clazz);
    if (strategy.isValidNewInstance(this, newInstance)) {
      // Only rewrite references to lambda classes if we are outside the class.
      if (shouldRewrite(newInstance.clazz)) {
        process(strategy, newInstance);
      }
    }
    return null;
  }

  @Override
  public Void visit(CheckCast checkCast) {
    lambdaChecker.accept(checkCast.getType());
    return null;
  }

  @Override
  public Void visit(NewArrayEmpty newArrayEmpty) {
    lambdaChecker.accept(newArrayEmpty.type);
    return null;
  }

  @Override
  public Void visit(ConstClass constClass) {
    lambdaChecker.accept(constClass.getValue());
    return null;
  }

  @Override
  public Void visit(ConstMethodType constMethodType) {
    lambdaChecker.accept(constMethodType.getValue());
    return null;
  }

  @Override
  public Void visit(ConstMethodHandle constMethodHandle) {
    lambdaChecker.accept(constMethodHandle.getValue());
    return null;
  }

  @Override
  public Void visit(InstanceGet instanceGet) {
    DexField field = instanceGet.getField();
    Strategy strategy = strategyProvider.apply(field.holder);
    if (strategy.isValidInstanceFieldRead(this, field)) {
      if (shouldRewrite(field)) {
        // Only rewrite references to lambda classes if we are outside the class.
        process(strategy, instanceGet);
      }
    } else {
      lambdaChecker.accept(field.type);
    }

    // We avoid fields with type being lambda class, it is possible for
    // a lambda to capture another lambda, but we don't support it for now.
    lambdaChecker.accept(field.type);
    return null;
  }

  @Override
  public Void visit(InstancePut instancePut) {
    DexField field = instancePut.getField();
    Strategy strategy = strategyProvider.apply(field.holder);
    if (strategy.isValidInstanceFieldWrite(this, field)) {
      if (shouldRewrite(field)) {
        // Only rewrite references to lambda classes if we are outside the class.
        process(strategy, instancePut);
      }
    } else {
      lambdaChecker.accept(field.type);
    }

    // We avoid fields with type being lambda class, it is possible for
    // a lambda to capture another lambda, but we don't support it for now.
    lambdaChecker.accept(field.type);
    return null;
  }

  @Override
  public Void visit(StaticGet staticGet) {
    DexField field = staticGet.getField();
    Strategy strategy = strategyProvider.apply(field.holder);
    if (strategy.isValidStaticFieldRead(this, field)) {
      if (shouldRewrite(field)) {
        // Only rewrite references to lambda classes if we are outside the class.
        process(strategy, staticGet);
      }
    } else {
      lambdaChecker.accept(field.type);
      lambdaChecker.accept(field.holder);
    }
    return null;
  }

  @Override
  public Void visit(StaticPut staticPut) {
    DexField field = staticPut.getField();
    Strategy strategy = strategyProvider.apply(field.holder);
    if (strategy.isValidStaticFieldWrite(this, field)) {
      if (shouldRewrite(field)) {
        // Only rewrite references to lambda classes if we are outside the class.
        process(strategy, staticPut);
      }
    } else {
      lambdaChecker.accept(field.type);
      lambdaChecker.accept(field.holder);
    }
    return null;
  }

  @Override
  public Void visit(InitClass initClass) {
    DexType clazz = initClass.getClassValue();
    Strategy strategy = strategyProvider.apply(clazz);
    if (strategy.isValidInitClass(this, clazz)) {
      if (shouldRewrite(clazz)) {
        // Only rewrite references to lambda classes if we are outside the class.
        process(strategy, initClass);
      }
    } else {
      lambdaChecker.accept(clazz);
    }
    return null;
  }

  abstract void process(Strategy strategy, InvokeMethod invokeMethod);

  abstract void process(Strategy strategy, NewInstance newInstance);

  abstract void process(Strategy strategy, InstancePut instancePut);

  abstract void process(Strategy strategy, InstanceGet instanceGet);

  abstract void process(Strategy strategy, StaticPut staticPut);

  abstract void process(Strategy strategy, StaticGet staticGet);

  abstract void process(Strategy strategy, InitClass initClass);
}
