// 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 com.android.tools.r8.TestBase.Backend;
import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.ListUtils;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.ImmutableMap;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;

// Base class for the runtime structure in the test parameters.
public abstract class TestRuntime {

  // Enum describing the possible/supported CF runtimes.
  public enum CfVm {
    JDK8("jdk8", 52),
    JDK9("jdk9", 53),
    JDK10("jdk10", 54),
    JDK11("jdk11", 55),
    JDK15("jdk15", 59),
    ;

    private final String name;
    private final int classfileVersion;

    CfVm(String name, int classfileVersion) {
      this.name = name;
      this.classfileVersion = classfileVersion;
    }

    public int getClassfileVersion() {
      return classfileVersion;
    }

    public static CfVm first() {
      return JDK8;
    }

    public static CfVm last() {
      return JDK11;
    }

    public boolean lessThan(CfVm other) {
      return this.ordinal() < other.ordinal();
    }

    public boolean lessThanOrEqual(CfVm other) {
      return this.ordinal() <= other.ordinal();
    }

    @Override
    public String toString() {
      return name;
    }
  }

  private static final Path JDK8_PATH = Paths.get(ToolHelper.THIRD_PARTY_DIR, "openjdk", "jdk8");
  private static final Path JDK9_PATH =
      Paths.get(ToolHelper.THIRD_PARTY_DIR, "openjdk", "openjdk-9.0.4");
  private static final Path JDK11_PATH = Paths.get(ToolHelper.THIRD_PARTY_DIR, "openjdk", "jdk-11");
  private static final Path JDK15_PATH = Paths.get(ToolHelper.THIRD_PARTY_DIR, "openjdk", "jdk-15");
  private static final Map<CfVm, Path> jdkPaths =
      ImmutableMap.of(
          CfVm.JDK8, JDK8_PATH,
          CfVm.JDK9, JDK9_PATH,
          CfVm.JDK11, JDK11_PATH,
          CfVm.JDK15, JDK15_PATH);

  public static CfRuntime getCheckedInJdk(CfVm vm) {
    if (vm == CfVm.JDK8) {
      return getCheckedInJdk8();
    }
    return new CfRuntime(vm, getCheckedInJdkHome(vm));
  }

  public static CfRuntime getCheckedInJdk8() {
    Path home;
    if (ToolHelper.isLinux()) {
      home = JDK8_PATH.resolve("linux-x86");
    } else if (ToolHelper.isMac()) {
      home = JDK8_PATH.resolve("darwin-x86");
    } else {
      assert ToolHelper.isWindows();
      return null;
    }
    return new CfRuntime(CfVm.JDK8, home);
  }

  private static Path getCheckedInJdkHome(CfVm vm) {
    Path path = jdkPaths.get(vm);
    assert path != null : "No JDK path defined for " + vm;
    if (ToolHelper.isLinux()) {
      return path.resolve("linux");
    } else if (ToolHelper.isMac()) {
      return vm.lessThanOrEqual(CfVm.JDK9)
          ? path.resolve("osx")
          : path.resolve("osx/Contents/Home");
    } else {
      assert ToolHelper.isWindows();
      return path.resolve("windows");
    }
  }

  public static CfRuntime getCheckedInJdk9() {
    return new CfRuntime(CfVm.JDK9, getCheckedInJdkHome(CfVm.JDK9));
  }

  public static CfRuntime getCheckedInJdk11() {
    return new CfRuntime(CfVm.JDK11, getCheckedInJdkHome(CfVm.JDK11));
  }

  // TODO(b/169692487): Add this to 'getCheckedInCfRuntimes' when we start having support for JDK15.
  public static CfRuntime getCheckedInJdk15() {
    return new CfRuntime(CfVm.JDK15, getCheckedInJdkHome(CfVm.JDK15));
  }

  public static List<CfRuntime> getCheckedInCfRuntimes() {
    CfRuntime[] jdks =
        new CfRuntime[] {getCheckedInJdk8(), getCheckedInJdk9(), getCheckedInJdk11()};
    Builder<CfRuntime> builder = ImmutableList.builder();
    for (CfRuntime jdk : jdks) {
      if (jdk != null) {
        builder.add(jdk);
      }
    }
    return builder.build();
  }

  private static List<DexRuntime> getCheckedInDexRuntimes() {
    if (ToolHelper.isLinux()) {
      return ListUtils.map(Arrays.asList(DexVm.Version.values()), DexRuntime::new);
    }
    assert ToolHelper.isMac() || ToolHelper.isWindows();
    return ImmutableList.of();
  }

  // For compatibility with old tests not specifying a Java runtime
  @Deprecated
  public static TestRuntime getDefaultJavaRuntime() {
    return getCheckedInJdk9();
  }

  public static List<TestRuntime> getCheckedInRuntimes() {
    return ImmutableList.<TestRuntime>builder()
        .addAll(getCheckedInCfRuntimes())
        .addAll(getCheckedInDexRuntimes())
        .build();
  }

  public static CfRuntime getSystemRuntime() {
    String version = System.getProperty("java.version");
    String home = System.getProperty("java.home");
    if (version == null || version.isEmpty() || home == null || home.isEmpty()) {
      throw new Unimplemented("Unable to create a system runtime");
    }
    if (version.startsWith("1.8.")) {
      return new CfRuntime(CfVm.JDK8, Paths.get(home));
    }
    if (version.startsWith("9.")) {
      return new CfRuntime(CfVm.JDK9, Paths.get(home));
    }
    if (version.startsWith("11.")) {
      return new CfRuntime(CfVm.JDK11, Paths.get(home));
    }
    throw new Unimplemented("No support for JDK version: " + version);
  }

  public static class NoneRuntime extends TestRuntime {

    private static final String NAME = "none";
    private static final NoneRuntime INSTANCE = new NoneRuntime();

    private NoneRuntime() {}

    public static NoneRuntime getInstance() {
      return INSTANCE;
    }

    @Override
    public String name() {
      return NAME;
    }

    @Override
    public AndroidApiLevel maxSupportedApiLevel() {
      // The "none" runtime trivally supports all api levels as nothing is run.
      return AndroidApiLevel.LATEST;
    }

    @Override
    public String toString() {
      return NAME;
    }

    @Override
    public boolean equals(Object other) {
      return this == other;
    }

    @Override
    public int hashCode() {
      return System.identityHashCode(this);
    }
  }

  // Wrapper for the DEX runtimes.
  public static class DexRuntime extends TestRuntime {

    private final DexVm vm;

    public DexRuntime(DexVm.Version version) {
      this(DexVm.fromVersion(version));
    }

    public DexRuntime(DexVm vm) {
      assert vm != null;
      this.vm = vm;
    }

    @Override
    public String name() {
      return "dex-" + vm.getVersion().toString();
    }

    @Override
    public boolean isDex() {
      return true;
    }

    @Override
    public DexRuntime asDex() {
      return this;
    }

    public DexVm getVm() {
      return vm;
    }

    @Override
    public AndroidApiLevel maxSupportedApiLevel() {
      return getMinApiLevel();
    }

    @Override
    public boolean equals(Object other) {
      if (!(other instanceof DexRuntime)) {
        return false;
      }
      DexRuntime dexRuntime = (DexRuntime) other;
      return vm == dexRuntime.vm;
    }

    @Override
    public int hashCode() {
      return vm.hashCode();
    }

    @Override
    public String toString() {
      return "dex-" + vm.getVersion().toString();
    }

    public AndroidApiLevel getMinApiLevel() {
      return ToolHelper.getMinApiLevelForDexVm(vm);
    }
  }

  // Wrapper for the CF runtimes.
  public static class CfRuntime extends TestRuntime {
    private final CfVm vm;
    private final Path home;

    public CfRuntime(CfVm vm, Path home) {
      assert vm != null;
      this.vm = vm;
      this.home = home.toAbsolutePath();
    }

    @Override
    public String name() {
      return vm.name().toLowerCase();
    }

    public Path getJavaHome() {
      return home;
    }

    public Path getJavaExecutable() {
      return home.resolve("bin").resolve("java");
    }

    @Override
    public boolean isCf() {
      return true;
    }

    @Override
    public CfRuntime asCf() {
      return this;
    }

    public CfVm getVm() {
      return vm;
    }

    @Override
    public AndroidApiLevel maxSupportedApiLevel() {
      // TODO: define the mapping from android API levels back to JDKs.
      return AndroidApiLevel.LATEST;
    }

    @Override
    public String toString() {
      return vm.toString();
    }

    @Override
    public boolean equals(Object obj) {
      if (!(obj instanceof CfRuntime)) {
        return false;
      }
      CfRuntime cfRuntime = (CfRuntime) obj;
      return vm == cfRuntime.vm && home.equals(cfRuntime.home);
    }

    @Override
    public int hashCode() {
      return Objects.hash(vm, home);
    }

    public boolean isOlderThan(CfVm version) {
      return vm.lessThan(version);
    }

    public boolean isNewerThan(CfVm version) {
      return !vm.lessThanOrEqual(version);
    }

    public boolean isNewerThanOrEqual(CfVm version) {
      return vm == version || !vm.lessThanOrEqual(version);
    }
  }

  public boolean isDex() {
    return false;
  }

  public boolean isCf() {
    return false;
  }

  public DexRuntime asDex() {
    return null;
  }

  public CfRuntime asCf() {
    return null;
  }

  public Backend getBackend() {
    if (isDex()) {
      return Backend.DEX;
    }
    if (isCf()) {
      return Backend.CF;
    }
    throw new Unreachable("Unexpected runtime without backend: " + this);
  }

  public abstract AndroidApiLevel maxSupportedApiLevel();

  @Override
  public abstract boolean equals(Object other);

  @Override
  public abstract int hashCode();

  public abstract String name();
}
