// 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.ir.desugar.desugaredlibrary.apiconversion;

import static com.android.tools.r8.ir.desugar.desugaredlibrary.apiconversion.DesugaredLibraryAPIConverter.vivifiedTypeFor;

import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.desugaredlibrary.apiconversion.DesugaredLibraryWrapperSynthesizerEventConsumer.DesugaredLibraryClasspathWrapperSynthesizeEventConsumer;
import com.android.tools.r8.ir.synthetic.apiconverter.NullableConversionCfCodeProvider.EnumConversionCfCodeProvider;
import com.android.tools.r8.synthesis.SyntheticClasspathClassBuilder;
import com.android.tools.r8.synthesis.SyntheticMethodBuilder;
import com.android.tools.r8.synthesis.SyntheticMethodBuilder.SyntheticCodeGenerator;
import com.android.tools.r8.synthesis.SyntheticProgramClassBuilder;
import com.google.common.collect.Iterables;

public class DesugaredLibraryEnumConversionSynthesizer {

  private final AppView<?> appView;
  private final DexItemFactory factory;

  public DesugaredLibraryEnumConversionSynthesizer(AppView<?> appView) {
    this.appView = appView;
    this.factory = appView.dexItemFactory();
  }

  private void buildEnumConvert(
      SyntheticMethodBuilder builder,
      DexType src,
      DexType dest,
      SyntheticCodeGenerator codeGenerator) {
    builder
        .setName(factory.convertMethodName)
        .setProto(factory.createProto(dest, src))
        .setAccessFlags(
            MethodAccessFlags.fromCfAccessFlags(
                Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC | Constants.ACC_STATIC, false))
        // Will be traced by the enqueuer.
        .disableAndroidApiLevelCheck()
        .setCode(codeGenerator);
  }

  private void buildEnumMethodsWithCode(
      SyntheticProgramClassBuilder builder,
      Iterable<DexEncodedField> enumFields,
      DexType enumType,
      DexType convertType) {
    builder
        .addMethod(
            methodBuilder ->
                buildEnumConvert(
                    methodBuilder,
                    enumType,
                    convertType,
                    codeSynthesizor ->
                        new EnumConversionCfCodeProvider(
                                appView,
                                codeSynthesizor.getHolderType(),
                                enumFields,
                                enumType,
                                convertType)
                            .generateCfCode()))
        .addMethod(
            methodBuilder ->
                buildEnumConvert(
                    methodBuilder,
                    convertType,
                    enumType,
                    codeSynthesizor ->
                        new EnumConversionCfCodeProvider(
                                appView,
                                codeSynthesizor.getHolderType(),
                                enumFields,
                                convertType,
                                enumType)
                            .generateCfCode()));
  }

  private void buildEnumMethodsWithoutCode(
      SyntheticClasspathClassBuilder builder, DexType enumType, DexType convertType) {
    builder
        .addMethod(
            methodBuilder ->
                buildEnumConvert(methodBuilder, enumType, convertType, ignored -> null))
        .addMethod(
            methodBuilder ->
                buildEnumConvert(methodBuilder, convertType, enumType, ignored -> null));
  }

  DexMethod ensureEnumConversionMethod(
      DexClass clazz,
      DexType srcType,
      DexType destType,
      DesugaredLibraryClasspathWrapperSynthesizeEventConsumer eventConsumer) {
    DexClass enumConversion = ensureEnumConversionClass(clazz, eventConsumer);
    DexMethod method =
        factory.createMethod(
            enumConversion.type, factory.createProto(destType, srcType), factory.convertMethodName);
    assert enumConversion.lookupDirectMethod(method) != null;
    return method;
  }

  DexMethod getExistingProgramEnumConversionMethod(
      DexClass clazz, DexType srcType, DexType destType) {
    DexProgramClass enumConversion =
        appView
            .getSyntheticItems()
            .getExistingFixedClass(kinds -> kinds.ENUM_CONVERSION, clazz, appView);
    DexMethod method =
        factory.createMethod(
            enumConversion.type, factory.createProto(destType, srcType), factory.convertMethodName);
    assert enumConversion.lookupProgramMethod(method) != null;
    return method;
  }

  DexProgramClass ensureProgramEnumConversionClass(
      DexClass context, CfClassSynthesizerDesugaringEventConsumer eventConsumer) {
    assert eventConsumer != null;
    assert context.isProgramClass();
    DexType type = context.type;
    DexType vivifiedType = vivifiedTypeFor(context.type, appView);
    assert appView.options().isDesugaredLibraryCompilation();
    DexProgramClass programContext = context.asProgramClass();
    Iterable<DexEncodedField> enumFields =
        Iterables.filter(programContext.staticFields(), DexEncodedField::isEnum);
    return appView
        .getSyntheticItems()
        .ensureFixedClass(
            kinds -> kinds.ENUM_CONVERSION,
            programContext,
            appView,
            builder -> buildEnumMethodsWithCode(builder, enumFields, type, vivifiedType),
            eventConsumer::acceptEnumConversionProgramClass);
  }

  private DexClass ensureEnumConversionClass(
      DexClass context, DesugaredLibraryClasspathWrapperSynthesizeEventConsumer eventConsumer) {
    assert eventConsumer != null;
    if (context.isProgramClass()) {
      return appView
          .getSyntheticItems()
          .getExistingFixedClass(kinds -> kinds.ENUM_CONVERSION, context, appView);
    }
    DexType type = context.type;
    DexType vivifiedType = vivifiedTypeFor(context.type, appView);
    return appView
        .getSyntheticItems()
        .ensureFixedClasspathClass(
            kinds -> kinds.ENUM_CONVERSION,
            context.asClasspathOrLibraryClass(),
            appView,
            builder -> buildEnumMethodsWithoutCode(builder, type, vivifiedType),
            eventConsumer::acceptEnumConversionClasspathClass);
  }
}
