// Copyright (c) 2022, 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.desugar.desugaredlibrary;

import com.android.tools.r8.androidapi.ComputedApiLevel;
import com.android.tools.r8.graph.AppView;
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.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexLibraryClass;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.FieldAccessFlags;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.utils.Reporter;
import java.util.Map;

/**
 * The LibraryAmender is responsible in amending the library so that desugared library can be
 * applied. For example, it can insert missing methods which are not present in the library but are
 * supported in desugared library.
 */
public class DesugaredLibraryAmender {

  private final DexDefinitionSupplier definitions;
  private final Reporter reporter;
  private final ComputedApiLevel minAPILevel;

  public static void run(AppView<?> appView) {
    run(
        appView.options().machineDesugaredLibrarySpecification.getAmendLibraryMethods(),
        appView.options().machineDesugaredLibrarySpecification.getAmendLibraryFields(),
        appView,
        appView.options().reporter,
        appView.computedMinApiLevel());
  }

  public static void run(
      Map<DexMethod, MethodAccessFlags> amendLibraryMethod,
      Map<DexField, FieldAccessFlags> amendLibraryField,
      DexDefinitionSupplier definitions,
      Reporter reporter,
      ComputedApiLevel minAPILevel) {
    if (amendLibraryMethod.isEmpty() && amendLibraryField.isEmpty()) {
      return;
    }
    new DesugaredLibraryAmender(definitions, reporter, minAPILevel)
        .run(amendLibraryMethod, amendLibraryField);
  }

  private DesugaredLibraryAmender(
      DexDefinitionSupplier definitions, Reporter reporter, ComputedApiLevel minAPILevel) {
    this.definitions = definitions;
    this.reporter = reporter;
    this.minAPILevel = minAPILevel;
  }

  private void run(
      Map<DexMethod, MethodAccessFlags> amendLibraryMethod,
      Map<DexField, FieldAccessFlags> amendLibraryField) {
    amendLibraryMethod.forEach(this::amendLibraryMethod);
    amendLibraryField.forEach(this::amendLibraryField);
  }

  private void amendLibraryField(DexField field, FieldAccessFlags fieldAccessFlags) {
    DexLibraryClass libClass = getLibraryClass(field);
    if (libClass == null) {
      return;
    }
    if (libClass.lookupField(field) != null) {
      return;
    }
    DexEncodedField encodedField =
        DexEncodedField.syntheticBuilder()
            .setField(field)
            .setAccessFlags(fieldAccessFlags)
            .setApiLevel(minAPILevel)
            .build();
    if (fieldAccessFlags.isStatic()) {
      libClass.appendStaticField(encodedField);
    } else {
      libClass.appendInstanceField(encodedField);
    }
  }

  private void amendLibraryMethod(DexMethod method, MethodAccessFlags methodAccessFlags) {
    DexLibraryClass libClass = getLibraryClass(method);
    if (libClass == null) {
      return;
    }
    if (libClass.lookupMethod(method) != null) {
      return;
    }
    DexEncodedMethod encodedMethod =
        DexEncodedMethod.syntheticBuilder()
            .setMethod(method)
            .setAccessFlags(methodAccessFlags)
            .setApiLevelForDefinition(minAPILevel)
            .build();
    libClass.getMethodCollection().addMethod(encodedMethod);
  }

  private DexLibraryClass getLibraryClass(DexReference reference) {
    DexClass dexClass = definitions.contextIndependentDefinitionFor(reference.getContextType());
    if (dexClass == null || !dexClass.isLibraryClass()) {
      // Consider just throwing an error.
      reporter.warning(
          "Desugared library: Cannot amend library reference "
              + reference
              + " because the holder is not a library class"
              + (dexClass == null ? "(null)." : "."));
      return null;
    }
    return dexClass.asLibraryClass();
  }
}
