// 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.cf.code.CfInstruction;
import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.ProgramMethod;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * A description of the desugaring task.
 *
 * <p>The description encodes if there are any side effects that must be done as part of the
 * desugaring checks (such as issue diagnostics) as well as if a given instruction needs to be
 * desugared, and if so, how to desugar it. The process of computing a description should be
 * side-effect free. All side effects should be done either in the 'scan' or the
 * 'desugarInstruction' callbacks.
 */
public class DesugarDescription {

  private static final DesugarDescription NOTHING = new DesugarDescription();

  private DesugarDescription() {}

  public void scan() {}

  public boolean needsDesugaring() {
    return false;
  }

  public Collection<CfInstruction> desugarInstruction(
      FreshLocalProvider freshLocalProvider,
      LocalStackAllocator localStackAllocator,
      CfInstructionDesugaringEventConsumer eventConsumer,
      ProgramMethod context,
      MethodProcessingContext methodProcessingContext,
      DexItemFactory dexItemFactory) {
    return null;
  }

  public static DesugarDescription nothing() {
    assert NOTHING == builder().build();
    return NOTHING;
  }

  public static Builder builder() {
    return InitialBuilder.getInstance();
  }

  @FunctionalInterface
  public interface ScanCallback {
    void scan();
  }

  @FunctionalInterface
  public interface DesugarCallback {
    Collection<CfInstruction> desugarInstruction(
        FreshLocalProvider freshLocalProvider,
        LocalStackAllocator localStackAllocator,
        CfInstructionDesugaringEventConsumer eventConsumer,
        ProgramMethod context,
        MethodProcessingContext methodProcessingContext,
        DexItemFactory dexItemFactory);
  }

  public abstract static class Builder {
    public abstract DesugarDescription build();

    public abstract Builder addScanEffect(ScanCallback callback);

    public abstract Builder setDesugarRewrite(DesugarCallback callback);
  }

  /**
   * Initial builder is an empty singleton. Any actual change will result in the allocation of a
   * non-empty builder. This ensures that the trivial case has zero allocation overhead.
   */
  static class InitialBuilder extends Builder {
    static final InitialBuilder INSTANCE = new InitialBuilder();

    public static InitialBuilder getInstance() {
      return INSTANCE;
    }

    @Override
    public DesugarDescription build() {
      return NOTHING;
    }

    @Override
    public Builder addScanEffect(ScanCallback callback) {
      return new NonEmptyBuilder().addScanEffect(callback);
    }

    @Override
    public Builder setDesugarRewrite(DesugarCallback callback) {
      return new NonEmptyBuilder().setDesugarRewrite(callback);
    }
  }

  static class NonEmptyBuilder extends Builder {

    List<ScanCallback> scanEffects = new ArrayList<>();
    DesugarCallback desugarRewrite = null;

    @Override
    public Builder addScanEffect(ScanCallback callback) {
      assert callback != null;
      scanEffects.add(callback);
      return this;
    }

    @Override
    public Builder setDesugarRewrite(DesugarCallback desugarRewrite) {
      assert this.desugarRewrite == null;
      assert desugarRewrite != null;
      this.desugarRewrite = desugarRewrite;
      return this;
    }

    @Override
    public DesugarDescription build() {
      return new DesugarDescription() {
        @Override
        public void scan() {
          scanEffects.forEach(ScanCallback::scan);
        }

        @Override
        public boolean needsDesugaring() {
          return desugarRewrite != null;
        }

        @Override
        public Collection<CfInstruction> desugarInstruction(
            FreshLocalProvider freshLocalProvider,
            LocalStackAllocator localStackAllocator,
            CfInstructionDesugaringEventConsumer eventConsumer,
            ProgramMethod context,
            MethodProcessingContext methodProcessingContext,
            DexItemFactory dexItemFactory) {
          return desugarRewrite == null
              ? null
              : desugarRewrite.desugarInstruction(
                  freshLocalProvider,
                  localStackAllocator,
                  eventConsumer,
                  context,
                  methodProcessingContext,
                  dexItemFactory);
        }
      };
    }
  }
}
