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

import static com.android.tools.r8.utils.DescriptorUtils.descriptorToJavaType;

import com.android.tools.r8.cf.code.CfConstString;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.code.ConstString;
import com.android.tools.r8.code.ConstStringJumbo;
import com.android.tools.r8.code.Instruction;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItem;
import com.android.tools.r8.graph.DexItemBasedString;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.graph.DexValue.DexValueString;
import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import com.android.tools.r8.shaking.ProguardClassFilter;
import java.util.Map;
import java.util.Set;

class IdentifierMinifier {

  private final AppInfoWithLiveness appInfo;
  private final ProguardClassFilter adaptClassStrings;
  private final NamingLens lens;
  private final Set<DexItem> identifierNameStrings;

  IdentifierMinifier(
      AppInfoWithLiveness appInfo, ProguardClassFilter adaptClassStrings, NamingLens lens) {
    this.appInfo = appInfo;
    this.adaptClassStrings = adaptClassStrings;
    this.lens = lens;
    this.identifierNameStrings = appInfo.identifierNameStrings;
  }

  void run() {
    if (!adaptClassStrings.isEmpty()) {
      adaptClassStrings();
    }
    if (!identifierNameStrings.isEmpty()) {
      replaceIdentifierNameString();
    }
  }

  private void adaptClassStrings() {
    for (DexProgramClass clazz : appInfo.classes()) {
      if (!adaptClassStrings.matches(clazz.type)) {
        continue;
      }
      clazz.forEachField(this::adaptClassStringsInField);
      clazz.forEachMethod(this::adaptClassStringsInMethod);
    }
  }

  private void adaptClassStringsInField(DexEncodedField encodedField) {
    if (!encodedField.accessFlags.isStatic()) {
      return;
    }
    DexValue staticValue = encodedField.getStaticValue();
    if (!(staticValue instanceof DexValueString)) {
      return;
    }
    DexString original = ((DexValueString) staticValue).getValue();
    DexString renamed = getRenamedStringLiteral(original);
    if (renamed != original) {
      encodedField.setStaticValue(new DexValueString(renamed));
    }
  }

  private void adaptClassStringsInMethod(DexEncodedMethod encodedMethod) {
    // Abstract methods do not have code_item.
    if (encodedMethod.accessFlags.isAbstract()) {
      return;
    }
    Code code = encodedMethod.getCode();
    if (code == null) {
      return;
    }
    if (code.isDexCode()) {
      DexCode dexCode = code.asDexCode();
      for (Instruction instr : dexCode.instructions) {
        if (instr instanceof ConstString) {
          ConstString cnst = (ConstString) instr;
          DexString dexString = cnst.getString();
          cnst.BBBB = getRenamedStringLiteral(dexString);
        } else if (instr instanceof ConstStringJumbo) {
          ConstStringJumbo cnst = (ConstStringJumbo) instr;
          DexString dexString = cnst.getString();
          cnst.BBBBBBBB = getRenamedStringLiteral(dexString);
        }
      }
    } else {
      assert code.isCfCode();
      CfCode cfCode = code.asCfCode();

      for (CfInstruction instr : cfCode.getInstructions()) {
        if (instr instanceof CfConstString) {
          CfConstString cnst = (CfConstString) instr;
          DexString dexString = cnst.getString();
          cnst.setString(getRenamedStringLiteral(dexString));
        }
      }
    }
  }

  private DexString getRenamedStringLiteral(DexString originalLiteral) {
    String originalString = originalLiteral.toString();
    Map<String, DexType> renamedYetMatchedTypes =
        lens.getRenamedItems(
            DexType.class,
            type -> type.toSourceString().equals(originalString),
            DexType::toSourceString);
    DexType type = renamedYetMatchedTypes.get(originalString);
    if (type != null) {
      DexString renamed = lens.lookupDescriptor(type);
      // Create a new DexString only when the corresponding string literal will be replaced.
      if (renamed != originalLiteral) {
        return appInfo.dexItemFactory.createString(descriptorToJavaType(renamed.toString()));
      }
    }
    return originalLiteral;
  }

  private void replaceIdentifierNameString() {
    for (DexProgramClass clazz : appInfo.classes()) {
      // Some const strings could be moved to field's static value (from <clinit>).
      clazz.forEachField(this::replaceIdentifierNameStringInField);
      clazz.forEachMethod(this::replaceIdentifierNameStringInMethod);
    }
  }

  private void replaceIdentifierNameStringInField(DexEncodedField encodedField) {
    if (!encodedField.accessFlags.isStatic()) {
      return;
    }
    DexValue staticValue = encodedField.getStaticValue();
    if (!(staticValue instanceof DexValueString)) {
      return;
    }
    DexString original = ((DexValueString) staticValue).getValue();
    if (original instanceof DexItemBasedString) {
      encodedField.setStaticValue(new DexValueString(materialize((DexItemBasedString) original)));
    }
  }

  private void replaceIdentifierNameStringInMethod(DexEncodedMethod encodedMethod) {
    if (!encodedMethod.getOptimizationInfo().useIdentifierNameString()) {
      return;
    }
    // Abstract methods do not have code_item.
    if (encodedMethod.accessFlags.isAbstract()) {
      return;
    }
    Code code = encodedMethod.getCode();
    if (code == null) {
      return;
    }
    if (code.isDexCode()) {
      DexCode dexCode = code.asDexCode();
      for (Instruction instr : dexCode.instructions) {
        if (instr instanceof ConstString
            && ((ConstString) instr).getString() instanceof DexItemBasedString) {
          ConstString cnst = (ConstString) instr;
          DexItemBasedString itemBasedString = (DexItemBasedString) cnst.getString();
          cnst.BBBB = materialize(itemBasedString);
        } else if (instr instanceof ConstStringJumbo
            && ((ConstStringJumbo) instr).getString() instanceof DexItemBasedString) {
          ConstStringJumbo cnst = (ConstStringJumbo) instr;
          DexItemBasedString itemBasedString = (DexItemBasedString) cnst.getString();
          cnst.BBBBBBBB = materialize(itemBasedString);
        }
      }
    } else {
      assert code.isCfCode();
      CfCode cfCode = code.asCfCode();

      for (CfInstruction instr : cfCode.getInstructions()) {
        if (instr instanceof CfConstString
            && ((CfConstString) instr).getString() instanceof DexItemBasedString) {
          CfConstString cnst = (CfConstString) instr;
          DexItemBasedString itemBasedString = (DexItemBasedString) cnst.getString();
          cnst.setString(materialize(itemBasedString));
        }
      }
    }
  }

  private DexString materialize(DexItemBasedString itemBasedString) {
    if (itemBasedString.basedOn instanceof DexType) {
      DexString renamed = lens.lookupDescriptor((DexType) itemBasedString.basedOn);
      if (!renamed.toString().equals(itemBasedString.toString())) {
        return appInfo.dexItemFactory.createString(descriptorToJavaType(renamed.toString()));
      }
      return renamed;
    } else if (itemBasedString.basedOn instanceof DexMethod) {
      return lens.lookupName((DexMethod) itemBasedString.basedOn);
    } else {
      assert itemBasedString.basedOn instanceof DexField;
      return lens.lookupName((DexField) itemBasedString.basedOn);
    }
  }
}
