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

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.shaking.ProguardConfigurationRule;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.ListUtils;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;

public class TestAppViewBuilder {

  private AndroidApp.Builder builder = AndroidApp.builder();
  private List<Function<DexItemFactory, List<ProguardConfigurationRule>>> rules = new ArrayList<>();
  private List<Consumer<InternalOptions>> optionModifications = new ArrayList<>();

  public static TestAppViewBuilder builder() {
    return new TestAppViewBuilder();
  }

  private TestAppViewBuilder() {}

  public TestAppViewBuilder addProgramClasses(Class<?>... classes) {
    return addProgramClasses(Arrays.asList(classes));
  }

  public TestAppViewBuilder addProgramClasses(Collection<Class<?>> classes) {
    classes.forEach(clazz -> builder.addProgramFile(ToolHelper.getClassFileForTestClass(clazz)));
    return this;
  }

  public TestAppViewBuilder addProgramClassFileData(byte[]... classes) {
    return addProgramClassFileData(Arrays.asList(classes));
  }

  public TestAppViewBuilder addProgramClassFileData(Collection<byte[]> classes) {
    builder.addClassProgramData(classes);
    return this;
  }

  public TestAppViewBuilder addAndroidApp(AndroidApp app) {
    app.getProgramResourceProviders().forEach(builder::addProgramResourceProvider);
    app.getClasspathResourceProviders().forEach(builder::addClasspathResourceProvider);
    app.getLibraryResourceProviders().forEach(builder::addLibraryResourceProvider);
    assert !app.hasMainDexList() : "todo";
    return this;
  }

  public TestAppViewBuilder addKeepAllRule() {
    rules = null;
    return this;
  }

  public TestAppViewBuilder addKeepMainRule(Class<?> mainClass) {
    return addKeepRuleBuilder(
        factory -> TestBase.buildKeepRuleForClassAndMethods(mainClass, factory));
  }

  public TestAppViewBuilder addKeepRuleBuilder(
      Function<DexItemFactory, List<ProguardConfigurationRule>> ruleBuilder) {
    if (rules != null) {
      rules.add(ruleBuilder);
    }
    return this;
  }

  public TestAppViewBuilder addOptionsModification(Consumer<InternalOptions> optionsConsumer) {
    optionModifications.add(optionsConsumer);
    return this;
  }

  public AppView<AppInfoWithLiveness> buildWithLiveness() throws Exception {
    return TestBase.computeAppViewWithLiveness(
        builder.build(),
        (rules == null
            ? null
            : factory ->
                TestBase.buildConfigForRules(
                    factory, ListUtils.flatMap(rules, r -> r.apply(factory)))),
        options -> optionModifications.forEach(consumer -> consumer.accept(options)));
  }

  public TestAppViewBuilder setMinApi(AndroidApiLevel minApi) {
    optionModifications.add(options -> options.setMinApiLevel(minApi));
    return this;
  }

  public TestAppViewBuilder addClasspathClasses(Class<?>... classes) {
    return addClasspathClasses(Arrays.asList(classes));
  }

  public TestAppViewBuilder addClasspathClasses(Collection<Class<?>> classes) {
    classes.forEach(clazz -> addClasspathFiles(ToolHelper.getClassFileForTestClass(clazz)));
    return this;
  }

  public TestAppViewBuilder addClasspathFiles(Path... files) {
    return addClasspathFiles(Arrays.asList(files));
  }

  public TestAppViewBuilder addClasspathFiles(List<Path> files) {
    builder.addClasspathFiles(files);
    return this;
  }

  public TestAppViewBuilder addLibraryFiles(Path... files) {
    return addLibraryFiles(Arrays.asList(files));
  }

  public TestAppViewBuilder addLibraryFiles(List<Path> files) {
    builder.addLibraryFiles(files);
    return this;
  }

  public TestAppViewBuilder addTestingAnnotations() {
    return addProgramClasses(TestBuilder.getTestingAnnotations());
  }
}
