// 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.TestBase.Backend;
import com.android.tools.r8.debug.DebugTestConfig;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.utils.AndroidApiLevel;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Collection;
import java.util.concurrent.ExecutionException;

public class IntermediateCfD8TestBuilder
    extends TestBuilder<D8TestRunResult, IntermediateCfD8TestBuilder> {

  public static IntermediateCfD8TestBuilder create(TestState state, AndroidApiLevel apiLevel) {
    assert state != null;
    assert apiLevel != null;
    return new IntermediateCfD8TestBuilder(state, apiLevel);
  }

  private final D8TestBuilder cf2cf;
  private final D8TestBuilder cf2dex;

  private IntermediateCfD8TestBuilder(TestState state, AndroidApiLevel apiLevel) {
    super(state);
    cf2cf = D8TestBuilder.create(state, Backend.CF).setMinApi(apiLevel);
    cf2dex =
        D8TestBuilder.create(state, Backend.DEX).setMinApi(apiLevel).setDisableDesugaring(true);
  }

  @Override
  IntermediateCfD8TestBuilder self() {
    return this;
  }

  @Override
  public D8TestRunResult run(TestRuntime runtime, String mainClass, String... args)
      throws CompilationFailedException, ExecutionException, IOException {
    return cf2dex.addProgramFiles(cf2cf.compile().writeToZip()).run(runtime, mainClass, args);
  }

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

  @Override
  public IntermediateCfD8TestBuilder addProgramFiles(Collection<Path> files) {
    cf2cf.addProgramFiles(files);
    return self();
  }

  @Override
  public IntermediateCfD8TestBuilder addProgramClassFileData(Collection<byte[]> classes) {
    cf2cf.addProgramClassFileData(classes);
    return self();
  }

  @Override
  public IntermediateCfD8TestBuilder addProgramDexFileData(Collection<byte[]> data) {
    cf2cf.addProgramDexFileData(data);
    return self();
  }

  @Override
  public IntermediateCfD8TestBuilder addLibraryFiles(Collection<Path> files) {
    cf2cf.addLibraryFiles(files);
    cf2dex.addLibraryFiles(files);
    return self();
  }

  @Override
  public IntermediateCfD8TestBuilder addLibraryClasses(Collection<Class<?>> classes) {
    cf2cf.addLibraryClasses(classes);
    cf2dex.addLibraryClasses(classes);
    return self();
  }

  @Override
  public IntermediateCfD8TestBuilder addClasspathClasses(Collection<Class<?>> classes) {
    cf2cf.addClasspathClasses(classes);
    cf2dex.addClasspathClasses(classes);
    return self();
  }

  @Override
  public IntermediateCfD8TestBuilder addClasspathFiles(Collection<Path> files) {
    cf2cf.addClasspathFiles(files);
    cf2dex.addClasspathFiles(files);
    return self();
  }

  @Override
  public IntermediateCfD8TestBuilder addRunClasspathFiles(Collection<Path> files) {
    cf2dex.addRunClasspathFiles(files);
    return self();
  }
}
