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

import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.utils.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.IntFunction;

/**
 * Specific subclass for Record field names. Record field names are specific DexString instances
 * used at the Java class file level for Records which encode the record field names in a single
 * String separated by semi-colon. The computation is able to minify and prune such names.
 *
 * <p>Example: record Person(String name, int age) {} The string is: name;age
 *
 * <p>The JVM normally generates the Record field names string such as it includes each field name
 * in the string. However, bytecode manipulation tools may rewrite the field name and not the
 * string. For this reason we have two subclasses. - MatchingRecordFieldNamesComputationInfo is used
 * when the name in the string matches the field names, and the R8 compilation is able to minify and
 * prune the string based on the fields. - MissMatchingRecordFieldNamesComputationInfo is used when
 * the name in the string does not match the field names, and the R8 compilation is then only able
 * to prune the fields while maintaining the non-matching field names.
 */
public abstract class RecordFieldNamesComputationInfo extends NameComputationInfo<DexType> {

  final DexField[] fields;

  protected RecordFieldNamesComputationInfo(DexField[] fields) {
    this.fields = fields;
  }

  private static class MissMatchingRecordFieldNamesComputationInfo
      extends RecordFieldNamesComputationInfo {

    private final String[] fieldNames;

    private MissMatchingRecordFieldNamesComputationInfo(String[] fieldNames, DexField[] fields) {
      super(fields);
      this.fieldNames = fieldNames;
    }

    @Override
    public DexString internalComputeNameFor(
        DexType type,
        DexDefinitionSupplier definitions,
        GraphLens graphLens,
        NamingLens namingLens) {
      return internalComputeNameFor(type, definitions, graphLens, i -> fieldNames[i]);
    }
  }

  private static class MatchingRecordFieldNamesComputationInfo
      extends RecordFieldNamesComputationInfo {

    public MatchingRecordFieldNamesComputationInfo(DexField[] fields) {
      super(fields);
    }

    @Override
    public DexString internalComputeNameFor(
        DexType type,
        DexDefinitionSupplier definitions,
        GraphLens graphLens,
        NamingLens namingLens) {
      return internalComputeNameFor(
          type,
          definitions,
          graphLens,
          i ->
              namingLens
                  .lookupField(
                      graphLens.getRenamedFieldSignature(fields[i]), definitions.dexItemFactory())
                  .name
                  .toString());
    }
  }

  static DexString dexStringFromFieldNames(List<String> fieldNames, DexItemFactory factory) {
    return factory.createString(StringUtils.join(";", fieldNames));
  }

  public static RecordFieldNamesComputationInfo forFieldNamesAndFields(
      DexString fieldNames, DexField[] fields) {
    String fieldNamesString = fieldNames.toString();
    String[] fieldNamesSplit =
        fieldNamesString.isEmpty() ? new String[0] : fieldNamesString.split(";");
    assert fieldNamesSplit.length == fields.length;
    if (fieldsMatchNames(fieldNamesSplit, fields)) {
      return new MatchingRecordFieldNamesComputationInfo(fields);
    }
    return new MissMatchingRecordFieldNamesComputationInfo(fieldNamesSplit, fields);
  }

  private static boolean fieldsMatchNames(String[] fieldNames, DexField[] fields) {
    for (int i = 0; i < fieldNames.length; i++) {
      if (!(fields[i].name.toString().equals(fieldNames[i]))) {
        return false;
      }
    }
    return true;
  }

  public DexString internalComputeNameFor(
      DexType type,
      DexDefinitionSupplier definitions,
      GraphLens graphLens,
      IntFunction<String> nameSupplier) {
    assert Arrays.stream(fields).allMatch(f -> f.holder == type);
    DexClass recordClass = definitions.contextIndependentDefinitionFor(type);
    assert recordClass != null;
    List<String> names = new ArrayList<>(fields.length);
    for (int i = 0; i < fields.length; i++) {
      DexEncodedField recordField =
          recordClass.lookupInstanceField(graphLens.getRenamedFieldSignature(fields[i]));
      if (recordField != null) {
        names.add(nameSupplier.apply(i));
      } else {
        // TODO(b/201277582): Temporarily work-around as long as the field values are not also
        //  shrunk in dex.
        names.add("<pruned>");
      }
    }
    return dexStringFromFieldNames(names, definitions.dexItemFactory());
  }

  @Override
  DexString internalComputeNameFor(
      DexType reference, DexDefinitionSupplier definitions, NamingLens namingLens) {
    throw new Unreachable();
  }

  public abstract DexString internalComputeNameFor(
      DexType type, DexDefinitionSupplier definitions, GraphLens graphLens, NamingLens namingLens);

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

  @Override
  public boolean needsToRegisterReference() {
    return false;
  }

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

  @Override
  public RecordFieldNamesComputationInfo asRecordFieldNamesComputationInfo() {
    return this;
  }
}
