// 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),
    JDK12("jdk12", 56),
    JDK13("jdk13", 57),
    JDK14("jdk14", 58),
    JDK15("jdk15", 59),
    JDK16("jdk16", 60),
    JDK17("jdk17", 61),
    JDK18("jdk18", 62),
    ;

    /** This should generally be the latest checked in CF runtime we fully support. */
    private static final CfVm DEFAULT = JDK11;

    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 JDK17;
    }

    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 JDK17_PATH = Paths.get(ToolHelper.THIRD_PARTY_DIR, "openjdk", "jdk-17");
  private static final Map<CfVm, Path> jdkPaths =
      ImmutableMap.of(
          CfVm.JDK8, JDK8_PATH,
          CfVm.JDK9, JDK9_PATH,
          CfVm.JDK11, JDK11_PATH,
          CfVm.JDK17, JDK17_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));
  }

  public static CfRuntime getCheckedInJdk17() {
    return new CfRuntime(CfVm.JDK17, getCheckedInJdkHome(CfVm.JDK17));
  }

  public static List<CfRuntime> getCheckedInCfRuntimes() {
    CfRuntime[] jdks =
        new CfRuntime[] {
          getCheckedInJdk8(), getCheckedInJdk9(), getCheckedInJdk11(), getCheckedInJdk17(),
        };
    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 CfRuntime getDefaultCfRuntime() {
    return TestRuntime.getCheckedInJdk(CfVm.DEFAULT);
  }

  public static DexRuntime getDefaultDexRuntime() {
    return new DexRuntime(DexVm.Version.NEW_DEFAULT);
  }

  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.equals("11") || 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;
    }

    public DexVm.Version getVersion() {
      return vm.getVersion();
    }

    @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();
}
