// 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.code;

import com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.ObjectToOffsetMapping;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.UseRegistry;
import com.android.tools.r8.ir.code.FieldMemberType;
import com.android.tools.r8.ir.conversion.IRBuilder;
import com.android.tools.r8.ir.conversion.LensCodeRewriterUtils;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.utils.structural.CompareToVisitor;
import com.android.tools.r8.utils.structural.StructuralSpecification;
import java.nio.ShortBuffer;

public class DexInitClass extends Base2Format {

  public static final int OPCODE = 0x60;
  public static final String NAME = "InitClass";
  public static final String SMALI_NAME = "initclass";

  private final int dest;
  private final DexType clazz;

  private static void specify(StructuralSpecification<DexInitClass, ?> spec) {
    spec.withInt(i -> i.dest).withItem(i -> i.clazz);
  }

  public DexInitClass(int dest, DexType clazz) {
    assert clazz.isClassType();
    this.dest = dest;
    this.clazz = clazz;
  }

  @Override
  public void buildIR(IRBuilder builder) {
    builder.addInitClass(dest, clazz);
  }

  @Override
  public void collectIndexedItems(
      IndexedItemCollection indexedItems,
      ProgramMethod context,
      GraphLens graphLens,
      LensCodeRewriterUtils rewriter) {
    // We intentionally apply the graph lens first, and then the init class lens, using the fact
    // that the init class lens maps classes in the final program to fields in the final program.
    DexType rewrittenClass = graphLens.lookupType(clazz);
    DexField clinitField = indexedItems.getInitClassLens().getInitClassField(rewrittenClass);
    clinitField.collectIndexedItems(indexedItems);
  }

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

  @Override
  public String getName() {
    return NAME;
  }

  @Override
  public String getSmaliName() {
    return SMALI_NAME;
  }

  @Override
  public int getOpcode() {
    throw new Unreachable();
  }

  @Override
  int getCompareToId() {
    return DexCompareHelper.INIT_CLASS_COMPARE_ID;
  }

  private int getOpcode(DexField field) {
    FieldMemberType type = FieldMemberType.fromDexType(field.type);
    switch (type) {
      case INT:
      case FLOAT:
        return Sget.OPCODE;
      case LONG:
      case DOUBLE:
        return SgetWide.OPCODE;
      case OBJECT:
        return SgetObject.OPCODE;
      case BOOLEAN:
        return SgetBoolean.OPCODE;
      case BYTE:
        return SgetByte.OPCODE;
      case CHAR:
        return SgetChar.OPCODE;
      case SHORT:
        return SgetShort.OPCODE;
      default:
        throw new Unreachable("Unexpected type: " + type);
    }
  }

  @Override
  public void registerUse(UseRegistry<?> registry) {
    registry.registerInitClass(clazz);
  }

  @Override
  public void write(
      ShortBuffer buffer,
      ProgramMethod context,
      GraphLens graphLens,
      ObjectToOffsetMapping mapping,
      LensCodeRewriterUtils rewriter) {
    // We intentionally apply the graph lens first, and then the init class lens, using the fact
    // that the init class lens maps classes in the final program to fields in the final program.
    DexType rewrittenClass = graphLens.lookupType(clazz);
    DexField clinitField = mapping.getClinitField(rewrittenClass);
    writeFirst(dest, buffer, getOpcode(clinitField));
    write16BitReference(clinitField, buffer, mapping);
  }

  @Override
  public int hashCode() {
    return ((clazz.hashCode() << 8) | dest) ^ getClass().hashCode();
  }

  @Override
  final int internalAcceptCompareTo(Instruction other, CompareToVisitor visitor) {
    return visitor.visit(this, (DexInitClass) other, DexInitClass::specify);
  }

  @Override
  public String toSmaliString(ClassNameMapper naming) {
    return formatSmaliString("v" + dest + ", " + clazz.toSmaliString());
  }

  @Override
  public String toString(ClassNameMapper naming) {
    StringBuilder builder = new StringBuilder("v").append(dest).append(", ");
    if (naming == null) {
      builder.append(clazz.toSourceString());
    } else {
      builder.append(naming.originalNameOf(clazz));
    }
    return formatString(builder.toString());
  }
}
