// Copyright (c) 2019, 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 static org.junit.Assert.assertNotNull;

import com.android.tools.r8.KotlinCompilerTool.KotlinCompiler;
import com.android.tools.r8.KotlinCompilerTool.KotlinCompilerVersion;
import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
import java.util.ArrayList;
import java.util.List;

public class KotlinTestParameters {

  private final int index;
  private final KotlinCompiler kotlinc;
  private final KotlinTargetVersion targetVersion;

  private KotlinTestParameters(
      KotlinCompiler kotlinc, KotlinTargetVersion targetVersion, int index) {
    this.index = index;
    this.kotlinc = kotlinc;
    this.targetVersion = targetVersion;
  }

  public KotlinCompiler getCompiler() {
    return kotlinc;
  }

  public KotlinTargetVersion getTargetVersion() {
    return targetVersion;
  }

  public boolean isFirst() {
    return index == 0;
  }

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

  @Override
  public String toString() {
    return kotlinc + "[target=" + targetVersion + "]";
  }

  public static class Builder {

    private KotlinCompiler[] compilers;
    private KotlinTargetVersion[] targetVersions;

    private Builder() {}

    public Builder withAllCompilers() {
      compilers = ToolHelper.getKotlinCompilers();
      return this;
    }

    public Builder withAllCompilersAndTargetVersions() {
      return withAllCompilers().withAllTargetVersions();
    }

    public Builder withCompiler(KotlinCompiler compiler) {
      compilers = new KotlinCompiler[] {compiler};
      return this;
    }

    public Builder withAllTargetVersions() {
      targetVersions = KotlinTargetVersion.values();
      return this;
    }

    public Builder withTargetVersion(KotlinTargetVersion targetVersion) {
      targetVersions = new KotlinTargetVersion[] {targetVersion};
      return this;
    }

    public KotlinTestParametersCollection build() {
      validate();
      List<KotlinTestParameters> testParameters = new ArrayList<>();
      int index = 0;
      for (KotlinCompiler kotlinc : compilers) {
        for (KotlinTargetVersion targetVersion : targetVersions) {
          // KotlinTargetVersion java 6 is deprecated from kotlinc 1.5 and forward, no need to run
          // tests on that target.
          if (targetVersion != KotlinTargetVersion.JAVA_6
              || kotlinc.isNot(KotlinCompilerVersion.KOTLINC_1_5_0_M2)) {
            testParameters.add(new KotlinTestParameters(kotlinc, targetVersion, index++));
          }
        }
      }
      return new KotlinTestParametersCollection(testParameters);
    }

    private void validate() {
      assertNotNull(compilers);
      assertNotNull(targetVersions);
    }
  }
}
