// Copyright (c) 2020, 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.debug.DebugTestConfig;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.utils.Pair;
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;

/** Abstraction to allow setup and execution of multiple test builders. */
public abstract class TestBuilderCollection<
        C extends Enum<C>,
        RR extends TestRunResultCollection<C, RR>,
        T extends TestBuilderCollection<C, RR, T>>
    extends TestBuilder<RR, T> {

  final List<Pair<C, TestBuilder<? extends TestRunResult<?>, ?>>> builders;

  TestBuilderCollection(
      TestState state, List<Pair<C, TestBuilder<? extends TestRunResult<?>, ?>>> builders) {
    super(state);
    assert !builders.isEmpty();
    this.builders = builders;
  }

  private T forEach(Consumer<TestBuilder<? extends TestRunResult<?>, ?>> fn) {
    builders.forEach(b -> fn.accept(b.getSecond()));
    return self();
  }

  @Override
  public DebugTestConfig debugConfig() {
    throw new Unimplemented("Unsupported debug config as of now...");
  }

  @Override
  public T addProgramFiles(Collection<Path> files) {
    return forEach(b -> b.addProgramFiles(files));
  }

  @Override
  public T addProgramClassFileData(Collection<byte[]> classes) {
    return forEach(b -> b.addProgramClassFileData(classes));
  }

  @Override
  public T addProgramDexFileData(Collection<byte[]> data) {
    return forEach(b -> b.addProgramDexFileData(data));
  }

  @Override
  public T addLibraryFiles(Collection<Path> files) {
    return forEach(b -> b.addLibraryFiles(files));
  }

  @Override
  public T addLibraryClasses(Collection<Class<?>> classes) {
    return forEach(b -> b.addLibraryClasses(classes));
  }

  @Override
  public T addClasspathClasses(Collection<Class<?>> classes) {
    return forEach(b -> b.addClasspathClasses(classes));
  }

  @Override
  public T addClasspathFiles(Collection<Path> files) {
    return forEach(b -> b.addClasspathFiles(files));
  }

  @Override
  public T addRunClasspathFiles(Collection<Path> files) {
    return forEach(b -> b.addRunClasspathFiles(files));
  }
}
