// 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 = JDK9;

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