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

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClassAndMethod;
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.BasicBlockIterator;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionListIterator;
import com.android.tools.r8.ir.code.InvokeMethod;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.shaking.ProguardConfiguration;
import java.util.Set;

public class LogMethodOptimizer extends StatelessLibraryMethodModelCollection {

  private static final int VERBOSE = 2;
  private static final int DEBUG = 3;
  private static final int INFO = 4;
  private static final int WARN = 5;
  private static final int ERROR = 6;
  private static final int ASSERT = 7;

  private final AppView<?> appView;

  private final DexType logType;

  private final DexMethod isLoggableMethod;
  private final DexMethod vMethod;
  private final DexMethod dMethod;
  private final DexMethod iMethod;
  private final DexMethod wMethod;
  private final DexMethod eMethod;
  private final DexMethod wtfMethod;

  LogMethodOptimizer(AppView<?> appView) {
    this.appView = appView;

    DexItemFactory dexItemFactory = appView.dexItemFactory();
    DexType logType = dexItemFactory.androidUtilLogType;
    this.logType = logType;
    this.isLoggableMethod =
        dexItemFactory.createMethod(
            logType,
            dexItemFactory.createProto(
                dexItemFactory.booleanType, dexItemFactory.stringType, dexItemFactory.intType),
            "isLoggable");
    this.vMethod =
        dexItemFactory.createMethod(
            logType,
            dexItemFactory.createProto(
                dexItemFactory.intType, dexItemFactory.stringType, dexItemFactory.stringType),
            "v");
    this.dMethod =
        dexItemFactory.createMethod(
            logType,
            dexItemFactory.createProto(
                dexItemFactory.intType, dexItemFactory.stringType, dexItemFactory.stringType),
            "d");
    this.iMethod =
        dexItemFactory.createMethod(
            logType,
            dexItemFactory.createProto(
                dexItemFactory.intType, dexItemFactory.stringType, dexItemFactory.stringType),
            "i");
    this.wMethod =
        dexItemFactory.createMethod(
            logType,
            dexItemFactory.createProto(
                dexItemFactory.intType, dexItemFactory.stringType, dexItemFactory.stringType),
            "w");
    this.eMethod =
        dexItemFactory.createMethod(
            logType,
            dexItemFactory.createProto(
                dexItemFactory.intType, dexItemFactory.stringType, dexItemFactory.stringType),
            "e");
    this.wtfMethod =
        dexItemFactory.createMethod(
            logType,
            dexItemFactory.createProto(
                dexItemFactory.intType, dexItemFactory.stringType, dexItemFactory.stringType),
            "wtf");
  }

  public static boolean isEnabled(AppView<?> appView) {
    ProguardConfiguration proguardConfiguration = appView.options().getProguardConfiguration();
    return proguardConfiguration != null
        && proguardConfiguration.getMaxRemovedAndroidLogLevel() >= VERBOSE;
  }

  @Override
  public DexType getType() {
    return logType;
  }

  @Override
  public void optimize(
      IRCode code,
      BasicBlockIterator blockIterator,
      InstructionListIterator instructionIterator,
      InvokeMethod invoke,
      DexClassAndMethod singleTarget,
      Set<Value> affectedValues,
      Set<BasicBlock> blocksToRemove) {
    int maxRemovedAndroidLogLevel =
        appView.options().getProguardConfiguration().getMaxRemovedAndroidLogLevel();
    if (singleTarget.getReference() == isLoggableMethod) {
      Value logLevelValue = invoke.arguments().get(1).getAliasedValue();
      if (!logLevelValue.isPhi() && !logLevelValue.hasLocalInfo()) {
        Instruction definition = logLevelValue.definition;
        if (definition.isConstNumber()) {
          int logLevel = definition.asConstNumber().getIntValue();
          replaceInvokeWithConstNumber(
              code, instructionIterator, invoke, maxRemovedAndroidLogLevel >= logLevel ? 0 : 1);
        }
      }
    } else if (singleTarget.getReference() == vMethod) {
      if (maxRemovedAndroidLogLevel >= VERBOSE) {
        replaceInvokeWithConstNumber(code, instructionIterator, invoke, 0);
      }
    } else if (singleTarget.getReference() == dMethod) {
      if (maxRemovedAndroidLogLevel >= DEBUG) {
        replaceInvokeWithConstNumber(code, instructionIterator, invoke, 0);
      }
    } else if (singleTarget.getReference() == iMethod) {
      if (maxRemovedAndroidLogLevel >= INFO) {
        replaceInvokeWithConstNumber(code, instructionIterator, invoke, 0);
      }
    } else if (singleTarget.getReference() == wMethod) {
      if (maxRemovedAndroidLogLevel >= WARN) {
        replaceInvokeWithConstNumber(code, instructionIterator, invoke, 0);
      }
    } else if (singleTarget.getReference() == eMethod) {
      if (maxRemovedAndroidLogLevel >= ERROR) {
        replaceInvokeWithConstNumber(code, instructionIterator, invoke, 0);
      }
    } else if (singleTarget.getReference() == wtfMethod) {
      if (maxRemovedAndroidLogLevel >= ASSERT) {
        replaceInvokeWithConstNumber(code, instructionIterator, invoke, 0);
      }
    }
  }

  private void replaceInvokeWithConstNumber(
      IRCode code, InstructionListIterator instructionIterator, InvokeMethod invoke, int value) {
    if (invoke.hasOutValue() && invoke.outValue().hasAnyUsers()) {
      instructionIterator.replaceCurrentInstructionWithConstInt(code, value);
    } else {
      instructionIterator.removeOrReplaceByDebugLocalRead();
    }
  }
}
