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

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer.D8CfInstructionDesugaringEventConsumer;
import com.android.tools.r8.utils.ThreadUtils;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;

public abstract class ClassConverter {

  protected final AppView<?> appView;
  private final IRConverter converter;
  private final D8MethodProcessor methodProcessor;

  ClassConverter(AppView<?> appView, IRConverter converter, D8MethodProcessor methodProcessor) {
    this.appView = appView;
    this.converter = converter;
    this.methodProcessor = methodProcessor;
  }

  public static ClassConverter create(
      AppView<?> appView, IRConverter converter, D8MethodProcessor methodProcessor) {
    return appView.options().desugarSpecificOptions().allowAllDesugaredInput
        ? new LibraryDesugaredClassConverter(appView, converter, methodProcessor)
        : new DefaultClassConverter(appView, converter, methodProcessor);
  }

  public ClassConverterResult convertClasses(ExecutorService executorService)
      throws ExecutionException {
    ClassConverterResult.Builder resultBuilder = ClassConverterResult.builder();
    internalConvertClasses(resultBuilder, executorService);
    notifyAllClassesConverted();
    return resultBuilder.build();
  }

  private void internalConvertClasses(
      ClassConverterResult.Builder resultBuilder, ExecutorService executorService)
      throws ExecutionException {
    List<DexProgramClass> classes = appView.appInfo().classes();
    while (!classes.isEmpty()) {
      Set<DexType> seenNestHosts = Sets.newIdentityHashSet();
      List<DexProgramClass> deferred = new ArrayList<>(classes.size() / 2);
      List<DexProgramClass> wave = new ArrayList<>(classes.size());
      for (DexProgramClass clazz : classes) {
        if (clazz.isInANest() && !seenNestHosts.add(clazz.getNestHost())) {
          deferred.add(clazz);
        } else {
          wave.add(clazz);

          // TODO(b/179755192): Avoid marking classes as scheduled by building up waves of methods.
          methodProcessor.addScheduled(clazz);
        }
      }

      // Process the wave and wait for all IR processing to complete.
      D8CfInstructionDesugaringEventConsumer desugaringEventConsumer =
          CfInstructionDesugaringEventConsumer.createForD8(methodProcessor);
      methodProcessor.newWave();
      ThreadUtils.processItems(
          wave, clazz -> convertClass(clazz, desugaringEventConsumer), executorService);
      methodProcessor.awaitMethodProcessing();

      // Finalize the desugaring of the processed classes. This may require processing (and
      // reprocessing) of some methods.
      List<ProgramMethod> needsProcessing =
          desugaringEventConsumer.finalizeDesugaring(appView, resultBuilder);
      if (!needsProcessing.isEmpty()) {
        // Create a new processor context to ensure unique method processing contexts.
        methodProcessor.newWave();

        // Process the methods that require reprocessing. These are all simple bridge methods and
        // should therefore not lead to additional desugaring.
        ThreadUtils.processItems(
            needsProcessing,
            method -> {
              DexEncodedMethod definition = method.getDefinition();
              if (definition.isProcessed()) {
                definition.markNotProcessed();
              }
              methodProcessor.processMethod(method, desugaringEventConsumer);
            },
            executorService);

        // Verify there is nothing to finalize once method processing finishes.
        methodProcessor.awaitMethodProcessing();
        assert desugaringEventConsumer.verifyNothingToFinalize();
      }

      classes = deferred;
    }
  }

  abstract void convertClass(
      DexProgramClass clazz, D8CfInstructionDesugaringEventConsumer desugaringEventConsumer);

  void convertMethods(
      DexProgramClass clazz, D8CfInstructionDesugaringEventConsumer desugaringEventConsumer) {
    converter.convertMethods(clazz, desugaringEventConsumer, methodProcessor);
  }

  abstract void notifyAllClassesConverted();

  static class DefaultClassConverter extends ClassConverter {

    DefaultClassConverter(
        AppView<?> appView, IRConverter converter, D8MethodProcessor methodProcessor) {
      super(appView, converter, methodProcessor);
    }

    @Override
    void convertClass(
        DexProgramClass clazz, D8CfInstructionDesugaringEventConsumer desugaringEventConsumer) {
      convertMethods(clazz, desugaringEventConsumer);
    }

    @Override
    void notifyAllClassesConverted() {
      // Intentionally empty.
    }
  }

  static class LibraryDesugaredClassConverter extends ClassConverter {

    private final Set<DexType> alreadyLibraryDesugared = Sets.newConcurrentHashSet();

    LibraryDesugaredClassConverter(
        AppView<?> appView, IRConverter converter, D8MethodProcessor methodProcessor) {
      super(appView, converter, methodProcessor);
    }

    @Override
    void convertClass(
        DexProgramClass clazz, D8CfInstructionDesugaringEventConsumer desugaringEventConsumer) {
      // Classes which has already been through library desugaring will not go through IR
      // processing again.
      LibraryDesugaredChecker libraryDesugaredChecker = new LibraryDesugaredChecker(appView);
      if (libraryDesugaredChecker.isClassLibraryDesugared(clazz)) {
        alreadyLibraryDesugared.add(clazz.getType());
      } else {
        convertMethods(clazz, desugaringEventConsumer);
      }
    }

    @Override
    void notifyAllClassesConverted() {
      appView.setAlreadyLibraryDesugared(alreadyLibraryDesugared);
    }
  }
}
