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

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.desugar.desugaredlibrary.apiconversion.DesugaredLibraryAPICallbackSynthesizer;
import com.android.tools.r8.ir.desugar.desugaredlibrary.disabledesugarer.DesugaredLibraryDisableDesugarerPostProcessor;
import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryRetargeterPostProcessor;
import com.android.tools.r8.ir.desugar.itf.InterfaceMethodProcessorFacade;
import com.android.tools.r8.ir.desugar.records.RecordDesugaring;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.function.Predicate;

public abstract class CfPostProcessingDesugaringCollection {

  public static CfPostProcessingDesugaringCollection create(
      AppView<?> appView,
      InterfaceMethodProcessorFacade interfaceMethodProcessorFacade,
      Predicate<ProgramMethod> isLiveMethod) {
    if (appView.options().desugarState.isOn()) {
      return NonEmptyCfPostProcessingDesugaringCollection.create(
          appView, interfaceMethodProcessorFacade, isLiveMethod);
    }
    return empty();
  }

  static CfPostProcessingDesugaringCollection empty() {
    return EmptyCfPostProcessingDesugaringCollection.getInstance();
  }

  public abstract void postProcessingDesugaring(
      Collection<DexProgramClass> programClasses,
      CfPostProcessingDesugaringEventConsumer eventConsumer,
      ExecutorService executorService)
      throws ExecutionException;

  public static class NonEmptyCfPostProcessingDesugaringCollection
      extends CfPostProcessingDesugaringCollection {

    private final List<CfPostProcessingDesugaring> desugarings;

    public NonEmptyCfPostProcessingDesugaringCollection(
        List<CfPostProcessingDesugaring> desugarings) {
      this.desugarings = desugarings;
    }

    public static CfPostProcessingDesugaringCollection create(
        AppView<?> appView,
        InterfaceMethodProcessorFacade interfaceMethodProcessorFacade,
        Predicate<ProgramMethod> isLiveMethod) {
      ArrayList<CfPostProcessingDesugaring> desugarings = new ArrayList<>();
      if (appView.options().machineDesugaredLibrarySpecification.hasRetargeting()
          && !appView.options().isDesugaredLibraryCompilation()) {
        desugarings.add(new DesugaredLibraryRetargeterPostProcessor(appView));
      }
      if (interfaceMethodProcessorFacade != null) {
        desugarings.add(interfaceMethodProcessorFacade);
      }
      DesugaredLibraryAPICallbackSynthesizer apiCallbackSynthesizor =
          appView.typeRewriter.isRewriting()
              ? new DesugaredLibraryAPICallbackSynthesizer(appView, isLiveMethod)
              : null;
      // At this point the desugaredLibraryAPIConverter is required to be last to generate
      // call-backs on the forwarding methods.
      if (apiCallbackSynthesizor != null) {
        desugarings.add(apiCallbackSynthesizor);
      }
      RecordDesugaring recordRewriter = RecordDesugaring.create(appView);
      if (recordRewriter != null) {
        desugarings.add(recordRewriter);
      }
      DesugaredLibraryDisableDesugarerPostProcessor disableDesugarer =
          DesugaredLibraryDisableDesugarerPostProcessor.create(appView);
      if (disableDesugarer != null) {
        desugarings.add(disableDesugarer);
      }
      if (desugarings.isEmpty()) {
        return empty();
      }
      return new NonEmptyCfPostProcessingDesugaringCollection(desugarings);
    }

    @Override
    public void postProcessingDesugaring(
        Collection<DexProgramClass> programClasses,
        CfPostProcessingDesugaringEventConsumer eventConsumer,
        ExecutorService executorService)
        throws ExecutionException {
      for (CfPostProcessingDesugaring desugaring : desugarings) {
        desugaring.postProcessingDesugaring(programClasses, eventConsumer, executorService);
      }
    }
  }

  public static class EmptyCfPostProcessingDesugaringCollection
      extends CfPostProcessingDesugaringCollection {

    private static final EmptyCfPostProcessingDesugaringCollection INSTANCE =
        new EmptyCfPostProcessingDesugaringCollection();

    private EmptyCfPostProcessingDesugaringCollection() {}

    private static EmptyCfPostProcessingDesugaringCollection getInstance() {
      return INSTANCE;
    }

    @Override
    public void postProcessingDesugaring(
        Collection<DexProgramClass> programClasses,
        CfPostProcessingDesugaringEventConsumer eventConsumer,
        ExecutorService executorService)
        throws ExecutionException {
      // Intentionally empty.
    }
  }
}
