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

import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.ir.code.If;
import com.android.tools.r8.ir.code.If.Type;
import com.android.tools.r8.ir.code.InstanceGet;
import com.android.tools.r8.ir.code.InstancePut;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.Invoke;
import com.android.tools.r8.ir.code.InvokeMethodWithReceiver;
import com.android.tools.r8.ir.code.InvokeStatic;
import com.android.tools.r8.ir.code.Monitor;
import com.android.tools.r8.ir.code.Return;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.Pair;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public final class ParameterUsagesInfo {

  private ImmutableList<ParameterUsage> parametersUsages;

  public ParameterUsagesInfo(List<ParameterUsage> usages) {
    assert !usages.isEmpty();
    parametersUsages = ImmutableList.copyOf(usages);
    assert parametersUsages.size() ==
        parametersUsages.stream().map(usage -> usage.index).collect(Collectors.toSet()).size();
  }

  public ParameterUsage getParameterUsage(int index) {
    for (ParameterUsage usage : parametersUsages) {
      if (usage.index == index) {
        return usage;
      }
    }
    return null;
  }

  ParameterUsagesInfo remove(int index) {
    assert parametersUsages.size() > 0;
    assert 0 <= index && index <= ListUtils.last(parametersUsages).index;
    ImmutableList.Builder<ParameterUsage> builder = ImmutableList.builder();
    for (ParameterUsage usage : parametersUsages) {
      // Once we remove or pass the designated index, copy-n-shift the remaining usages.
      if (index < usage.index) {
        builder.add(ParameterUsage.copyAndShift(usage, 1));
      } else if (index == usage.index) {
        // Do not add the parameter usage with the matched index.
      } else {
        // Until we meet the `parameter` of interest, keep copying.
        assert usage.index < index;
        builder.add(usage);
      }
    }
    ImmutableList<ParameterUsage> adjustedUsages = builder.build();
    if (adjustedUsages.isEmpty()) {
      return DefaultMethodOptimizationInfo.UNKNOWN_PARAMETER_USAGE_INFO;
    }
    return new ParameterUsagesInfo(adjustedUsages);
  }

  public final static class ParameterUsage {

    public final int index;
    public final Set<Type> ifZeroTest;
    public final List<Pair<Invoke.Type, DexMethod>> callsReceiver;

    // If a field of this argument is assigned: arg.f = x.
    public final boolean hasFieldAssignment;

    // If a field of this argument is read: x = arg.f.
    public final boolean hasFieldRead;

    // If this argument is assigned to a field: x.f = arg.
    public final boolean isAssignedToField;

    // If this argument is returned: return arg.
    public final boolean isReturned;

    // If this argument is used in a monitor instruction.
    public final boolean isUsedInMonitor;

    ParameterUsage(
        int index,
        Set<Type> ifZeroTest,
        List<Pair<Invoke.Type, DexMethod>> callsReceiver,
        boolean hasFieldAssignment,
        boolean hasFieldRead,
        boolean isAssignedToField,
        boolean isReturned,
        boolean isUsedInMonitor) {
      this.index = index;
      this.ifZeroTest =
          ifZeroTest.isEmpty() ? Collections.emptySet() : ImmutableSet.copyOf(ifZeroTest);
      this.callsReceiver =
          callsReceiver.isEmpty() ? Collections.emptyList() : ImmutableList.copyOf(callsReceiver);
      this.hasFieldAssignment = hasFieldAssignment;
      this.hasFieldRead = hasFieldRead;
      this.isAssignedToField = isAssignedToField;
      this.isReturned = isReturned;
      this.isUsedInMonitor = isUsedInMonitor;
    }

    static ParameterUsage copyAndShift(ParameterUsage original, int shift) {
      assert original.index >= shift;
      return new ParameterUsage(
          original.index - shift,
          original.ifZeroTest,
          original.callsReceiver,
          original.hasFieldAssignment,
          original.hasFieldRead,
          original.isAssignedToField,
          original.isReturned,
          original.isUsedInMonitor);
    }

    public boolean notUsed() {
      return (ifZeroTest == null || ifZeroTest.isEmpty())
          && (callsReceiver == null || callsReceiver.isEmpty())
          && !hasFieldAssignment
          && !hasFieldRead
          && !isAssignedToField
          && !isReturned
          && !isUsedInMonitor;
    }
  }

  public static class ParameterUsageBuilder {

    private final int index;
    private final Value arg;
    private final DexItemFactory dexItemFactory;

    private final Set<Type> ifZeroTestTypes = new HashSet<>();
    private final List<Pair<Invoke.Type, DexMethod>> callsOnReceiver = new ArrayList<>();

    private boolean hasFieldAssignment = false;
    private boolean hasFieldRead = false;
    private boolean isAssignedToField = false;
    private boolean isReturned = false;
    private boolean isUsedInMonitor = false;

    ParameterUsageBuilder(Value arg, int index, DexItemFactory dexItemFactory) {
      this.arg = arg;
      this.index = index;
      this.dexItemFactory = dexItemFactory;
    }

    // Returns false if the instruction is not supported.
    public boolean note(Instruction instruction) {
      if (instruction.isAssume()) {
        // Keep examining other users if there are no phi users, but the param usage builder should
        // consider aliased users.
        return !instruction.outValue().hasPhiUsers();
      }
      if (instruction.isIf()) {
        return note(instruction.asIf());
      }
      if (instruction.isInstanceGet()) {
        return note(instruction.asInstanceGet());
      }
      if (instruction.isInstancePut()) {
        return note(instruction.asInstancePut());
      }
      if (instruction.isInvokeMethodWithReceiver()) {
        return note(instruction.asInvokeMethodWithReceiver());
      }
      if (instruction.isInvokeStatic()) {
        return note(instruction.asInvokeStatic());
      }
      if (instruction.isReturn()) {
        return note(instruction.asReturn());
      }
      if (instruction.isMonitor()) {
        return note(instruction.asMonitor());
      }
      return false;
    }

    public ParameterUsage build() {
      return new ParameterUsage(
          index,
          ifZeroTestTypes,
          callsOnReceiver,
          hasFieldAssignment,
          hasFieldRead,
          isAssignedToField,
          isReturned,
          isUsedInMonitor);
    }

    private boolean note(If ifInstruction) {
      if (ifInstruction.asIf().isZeroTest()) {
        assert ifInstruction.inValues().size() == 1
            && ifInstruction.inValues().get(0).getAliasedValue() == arg;
        ifZeroTestTypes.add(ifInstruction.asIf().getType());
        return true;
      }
      return false;
    }

    private boolean note(InstanceGet instanceGetInstruction) {
      assert arg != instanceGetInstruction.outValue();
      if (instanceGetInstruction.object().getAliasedValue() == arg) {
        hasFieldRead = true;
        return true;
      }
      return false;
    }

    private boolean note(InstancePut instancePutInstruction) {
      assert arg != instancePutInstruction.outValue();
      if (instancePutInstruction.object().getAliasedValue() == arg) {
        hasFieldAssignment = true;
        isAssignedToField |= instancePutInstruction.value().getAliasedValue() == arg;
        return true;
      }
      if (instancePutInstruction.value().getAliasedValue() == arg) {
        isAssignedToField = true;
        return true;
      }
      return false;
    }

    private boolean note(InvokeMethodWithReceiver invokeInstruction) {
      if (ListUtils.lastIndexMatching(
          invokeInstruction.inValues(), v -> v.getAliasedValue() == arg) == 0) {
        callsOnReceiver.add(
            new Pair<>(
                invokeInstruction.asInvokeMethodWithReceiver().getType(),
                invokeInstruction.asInvokeMethodWithReceiver().getInvokedMethod()));
        return true;
      }
      return false;
    }

    private boolean note(InvokeStatic invokeInstruction) {
      if (invokeInstruction.getInvokedMethod() == dexItemFactory.objectsMethods.requireNonNull) {
        if (!invokeInstruction.hasOutValue() || !invokeInstruction.outValue().hasAnyUsers()) {
          ifZeroTestTypes.add(Type.EQ);
          return true;
        }
      }
      return false;
    }

    private boolean note(Return returnInstruction) {
      assert returnInstruction.inValues().size() == 1
          && returnInstruction.inValues().get(0).getAliasedValue() == arg;
      isReturned = true;
      return true;
    }

    private boolean note(Monitor monitorInstruction) {
      assert monitorInstruction.inValues().size() == 1;
      assert monitorInstruction.inValues().get(0).getAliasedValue() == arg;
      isUsedInMonitor = true;
      return true;
    }
  }
}
