// Copyright (c) 2017, 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.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.FileListingService;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.IShellOutputReceiver;
import com.android.ddmlib.ShellCommandUnresponsiveException;
import com.android.ddmlib.SyncException;
import com.android.ddmlib.TimeoutException;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.base.Joiner;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * This class is used to run tests on devices (or emulators)
 * using ddmlib.
 */
public class DeviceRunner {

  private static final boolean VERBOSE = false;
  private static final long ADB_CONNECTION_TIMEOUT = 5000;
  private static final long ADB_WAIT_STEP = ADB_CONNECTION_TIMEOUT / 10;
  private static final String TEST_SCRIPT_NAME = "test-exit-status.sh";
  private static final File TEST_SCRIPT_FILE =
      new File(System.getProperty("user.dir"), "scripts/" + TEST_SCRIPT_NAME);
  private static final char PATH_SEPARATOR_CHAR = ':';
  private static final String RUNTIME_NAME = "ART";

  private List<String> vmOptions = Collections.emptyList();
  private Map<String, String> systemProperties = Collections.emptyMap();
  private List<File> classpath = Collections.emptyList();
  private List<File> bootClasspath = Collections.emptyList();
  private String mainClass;
  private List<String> programArguments = Collections.emptyList();
  private OutputStream outRedirectStream = new ByteArrayOutputStream();

  private ShellOutputReceiver hostOutput = new ShellOutputReceiver();

  public static class DeviceRunnerConfigurationException extends Exception {

    public DeviceRunnerConfigurationException(String message) {
      super(message);
    }
  }

  private static class ShellOutputReceiver implements IShellOutputReceiver {

    private final PrintStream out;

    public ShellOutputReceiver() {
      this.out = System.out;
    }

    public ShellOutputReceiver(OutputStream out) {
      this.out = new PrintStream(out);
    }

    @Override
    public void addOutput(byte[] data, int offset, int length) {
      out.print(new String(Arrays.copyOfRange(data, offset, offset + length)));
    }

    @Override
    public void flush() {
    }

    @Override
    public boolean isCancelled() {
      return false;
    }
  }

  private static class ShellOutputToStringReceiver implements IShellOutputReceiver {

    StringBuffer outBuffer = new StringBuffer();

    @Override
    public void addOutput(byte[] data, int offset, int length) {
      outBuffer.append(new String(Arrays.copyOfRange(data, offset, offset + length)));
    }

    @Override
    public void flush() {
    }

    @Override
    public boolean isCancelled() {
      return false;
    }

    public String getOutput() {
      return outBuffer.toString();
    }
  }

  public DeviceRunner() {
    try {
      AndroidDebugBridge.init(/* clientSupport */ false);
    } catch (IllegalStateException ex) {
      // ADB was already initialized, we're fine, so just ignore.
    }
  }

  public DeviceRunner setVmOptions(List<String> vmOptions) {
    this.vmOptions = vmOptions;
    return this;
  }

  public DeviceRunner setSystemProperties(Map<String, String> systemProperties) {
    this.systemProperties = systemProperties;
    return this;
  }

  public DeviceRunner setClasspath(List<File> classpath) {
    this.classpath = classpath;
    return this;
  }

  public DeviceRunner setBootClasspath(List<File> bootClasspath) {
    this.bootClasspath = bootClasspath;
    return this;
  }

  public DeviceRunner setMainClass(String mainClass) {
    this.mainClass = mainClass;
    return this;
  }

  public DeviceRunner setProgramArguments(List<String> programArguments) {
    this.programArguments = programArguments;
    return this;
  }

  public DeviceRunner setOutputStream(OutputStream outputStream) {
    outRedirectStream = outputStream;
    return this;
  }

  public ToolHelper.ProcessResult run() throws DeviceRunnerConfigurationException, IOException {

    AndroidDebugBridge adb = initializeAdb();

    IDevice[] connectedDevices = adb.getDevices();
    if (connectedDevices.length == 0) {
      throw new DeviceRunnerConfigurationException("No device found");
    }

    if (connectedDevices.length != 1) {
      throw new DeviceRunnerConfigurationException(
          "Running tests on more than one device is not yet supported. "
              + "Currently connected devices: ["
              + StringUtils.join(",", Arrays.asList(connectedDevices))
              + "]");
    }

    int exitStatus = -1;
    String uuid = java.util.UUID.randomUUID().toString();
    IDevice device = connectedDevices[0];
    try {
      checkDeviceRuntime(device);

      log("Running on device: " + device.getName());

      ensureAdbRoot(device);

      // Remove trailing '\n' returned by emulator
      File testsRootDirFile = new File(device.getMountPoint(IDevice.MNT_DATA).replace("\n", ""),
          "r8-tests-" + uuid);
      String testsRootDir = convertToTargetPath(testsRootDirFile);

      String testScriptPathOnTarget = convertToTargetPath(
          new File(testsRootDirFile, TEST_SCRIPT_NAME));

      ClasspathPair destFilePaths = installTestFiles(device, testsRootDirFile,
          testScriptPathOnTarget);

      File rootDir = new File(device.getMountPoint(IDevice.MNT_ROOT).replace("\n", ""));

      // Bug : exit code return by adb shell is wrong (always 0)
      // https://code.google.com/p/android/issues/detail?id=3254
      // Use go team hack to work this around
      // https://code.google.com/p/go/source/browse/misc/arm/a
      executeShellCommand(testScriptPathOnTarget + ' ' + uuid + ' ' + Joiner.on(' ').join(
          buildCommandLine(rootDir, testsRootDir, destFilePaths.bootclasspath,
              destFilePaths.classpath)), device, new ShellOutputReceiver(outRedirectStream),
          /* maxTimeToOutputResponse = */10000);
      exitStatus = getExitStatus(device, testsRootDir);
      log("Exit status: " + exitStatus);

      if (exitStatus != 0) {
        System.err.println("Execution failed on device '" + device.getName() + "'");
      }

    } catch (IOException t) {
      System.err.println("Error with device '" + device.getName() + "': " + t.getMessage());
      t.printStackTrace();
      throw t;
    } finally {
      deleteTestFiles(device, uuid);
    }

    // Convert target line separator to whatever host is for output comparison-based tests
    String outputAsString = outRedirectStream.toString()
        .replace("\n", ToolHelper.LINE_SEPARATOR);

    return new ToolHelper.ProcessResult(exitStatus, outputAsString, "");
  }

  private AndroidDebugBridge initializeAdb() throws DeviceRunnerConfigurationException {
    AndroidDebugBridge adb = AndroidDebugBridge.createBridge(getAdbLocation(), false);

    long start = System.currentTimeMillis();

    log("Initializing adb...");

    while (!isAdbInitialized(adb)) {
      long timeLeft = start + ADB_CONNECTION_TIMEOUT - System.currentTimeMillis();
      if (timeLeft <= 0) {
        break;
      }
      try {
        Thread.sleep(ADB_WAIT_STEP);
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new AssertionError(e);
      }
    }

    if (!isAdbInitialized(adb)) {
      String userDefinedPathToSdk = System.getProperty("ANDROID_SDK_HOME");
      if (userDefinedPathToSdk != null) {
        throw new DeviceRunnerConfigurationException(
            "Adb not found. Check SDK location '"
                + userDefinedPathToSdk
                + "'");
      } else {
        throw new DeviceRunnerConfigurationException(
            "Adb not found. Set either PATH or ANDROID_SDK_HOME environment variable");
      }
    }

    log("Done");
    return adb;
  }

  private static class ClasspathPair {
    public String[] bootclasspath;
    public String[] classpath;

    ClasspathPair(String[] bootclasspath, String[] classpath) {
      this.bootclasspath = bootclasspath;
      this.classpath = classpath;
    }
  }

  /**
   * @return path of classpath and bootclasspath files on device
   */
  private ClasspathPair installTestFiles(IDevice device, File testsRootDirFile,
      String testScriptPathOnTarget) throws IOException {

    String testsRootDir = convertToTargetPath(testsRootDirFile);

    String[] desFilePaths = new String[classpath.size()];
    String[] destFileBootCpPaths = new String[bootClasspath.size()];

    executeShellCommand("mkdir " + testsRootDir, device);
    executeShellCommand(
        "rm " + testsRootDir + FileListingService.FILE_SEPARATOR + "*", device);
    executePushCommand(TEST_SCRIPT_FILE.getAbsolutePath(), testScriptPathOnTarget, device);
    executeShellCommand("chmod 777 " + testScriptPathOnTarget, device);

    int i = 0;
    for (File f : bootClasspath) {
      destFileBootCpPaths[i] = convertToTargetPath(
          new File(testsRootDirFile, "f" + i + "_" + f.getName()));
      executePushCommand(f.getAbsolutePath(), destFileBootCpPaths[i], device);
      i++;
    }
    i = 0;
    for (File f : classpath) {
      desFilePaths[i] = convertToTargetPath(
          new File(testsRootDirFile, "f" + i + "_" + f.getName()));
      executePushCommand(f.getAbsolutePath(), desFilePaths[i], device);
      i++;
    }
    return new ClasspathPair(destFileBootCpPaths, desFilePaths);
  }

  private int getExitStatus(IDevice device, String testsRootDir) throws IOException {
    File exitStatusFile = createTempFile("exitStatus", "");
    executePullCommand(
        testsRootDir + "/exitStatus", exitStatusFile.getAbsolutePath(), device);

    try (BufferedReader br = new BufferedReader(new FileReader(exitStatusFile))) {
      String readLine = br.readLine();
      if (readLine == null) {
        throw new FileNotFoundException("Exit status not found at " + exitStatusFile.getPath());
      }
      return Integer.parseInt(readLine);
    }
  }

  @SuppressWarnings("deprecation")
  private void executeShellCommand(
      String command,
      IDevice device,
      ShellOutputReceiver hostOutput,
      int maxTimeToOutputResponse) throws IOException {
    log("adb -s " + device.getSerialNumber() + " shell " + command);
    try {
      if (maxTimeToOutputResponse != -1) {
        device.executeShellCommand(command, hostOutput, maxTimeToOutputResponse);
      } else {
        device.executeShellCommand(command, hostOutput);
      }
    } catch (IOException
        | ShellCommandUnresponsiveException
        | TimeoutException
        | AdbCommandRejectedException e) {
      throw new IOException(
          "Failed to execute shell command: '" + command + "'", e);
    }
  }

  private void executeShellCommand(String command, IDevice device)
      throws IOException {
    executeShellCommand(command, device, hostOutput, -1);
  }

  private void executePushCommand(
      String srcFile, String destFile, IDevice device) throws IOException {
    log("adb -s " + device.getSerialNumber() + " push " + srcFile + " " + destFile);
    try {
      device.pushFile(srcFile, destFile);
    } catch (IOException | AdbCommandRejectedException | TimeoutException | SyncException e) {
      throw new IOException(
          "Unable to push file '" + srcFile + "' on device into '" + destFile + "'", e);
    }
  }

  private void executePullCommand(
      String srcFile, String destFile, IDevice device) throws IOException {
    log("adb -s " + device.getSerialNumber() + " pull " + srcFile + " " + destFile);
    try {
      device.pullFile(srcFile, destFile);
    } catch (IOException | AdbCommandRejectedException | TimeoutException | SyncException e) {
      throw new IOException(
          "Unable to pull file '" + srcFile + "' from device into '" + destFile + "'", e);
    }
  }

  private boolean isAdbInitialized(AndroidDebugBridge adb) {
    return adb.isConnected() && adb.hasInitialDeviceList();
  }

  private String getAdbLocation() {
    String adbLocation = "adb";
    String userSpecifiedSdkLocation = System.getenv("ANDROID_SDK_HOME");
    if (userSpecifiedSdkLocation != null) {
      adbLocation =
          userSpecifiedSdkLocation
              + File.separatorChar
              + "platform-tools"
              + File.separatorChar
              + "adb";
    }
    return adbLocation;
  }


  private void ensureAdbRoot(IDevice device) throws IOException {
    boolean isRoot;
    try {
      isRoot = device.isRoot();
    } catch (TimeoutException
        | AdbCommandRejectedException
        | IOException
        | ShellCommandUnresponsiveException e) {
      throw new IOException(
          "Cannot fetch root status for device '"
              + device.getName()
              + "("
              + device.getSerialNumber()
              + ")"
              + "': "
              + e.getMessage(),
          e);
    }

    int numberOfTries = 0;
    while (!isRoot && numberOfTries < 5) {
      try {
        isRoot = device.root();
      } catch (TimeoutException
          | AdbCommandRejectedException
          | IOException
          | ShellCommandUnresponsiveException e1) {
        // root() seems to throw an IOException: EOF, and it tends
        // to make the subsequent call to isRoot() fail with
        // AdbCommandRejectedException: device offline, until adbd is
        // restarted as root.
      } finally {
        try {
          Thread.sleep(1000);
        } catch (InterruptedException e1) {
          Thread.currentThread().interrupt();
        }
      }
      numberOfTries++;
    }

    if (!isRoot) {
      throw new IOException(
          "Cannot switch to root on device '"
              + device.getName()
              + "("
              + device.getSerialNumber()
              + ")"
              + "'");
    }
  }

  private void checkDeviceRuntime(IDevice device)
      throws DeviceRunnerConfigurationException, IOException {
    ShellOutputToStringReceiver outputToString = new ShellOutputToStringReceiver();
    try {
      device.executeShellCommand("dalvikvm -showversion", outputToString);
      if (!outputToString.getOutput().contains(RUNTIME_NAME)) {
        throw new DeviceRunnerConfigurationException(
            "The plugged device does not run the required runtime: '" + RUNTIME_NAME + "'");
      }
    } catch (TimeoutException
        | AdbCommandRejectedException
        | ShellCommandUnresponsiveException
        | IOException e) {
      throw new IOException("Could not check device runtime", e);
    }
  }

  private String convertToTargetPath(File file) {
    String path = file.getPath();
    Path root = file.toPath().getRoot();
    if (root != null) {
      path = path.replace(root.toString(), FileListingService.FILE_SEPARATOR);
    }
    return path.replace(File.separator, FileListingService.FILE_SEPARATOR);
  }

  private static File createTempFile(String prefix, String suffix) throws IOException {
    File tmp = File.createTempFile("r8-tests-" + prefix, suffix);
    tmp.deleteOnExit();
    return tmp;
  }

  private void deleteTestFiles(IDevice device, String uuid) throws IOException {
    String deleteCommand = "find data -name '*r8-tests-" + uuid + "*' -exec rm -rf {} +";
    log("adb -s " + device.getSerialNumber() + " shell " + deleteCommand);
    try {
      device.executeShellCommand(deleteCommand, hostOutput);
    } catch (TimeoutException
        | AdbCommandRejectedException
        | ShellCommandUnresponsiveException
        | IOException e) {
      throw new IOException("Error while deleting test file on device", e);
    }
  }

  private List<String> buildCommandLine(File rootDir, String testRootDir,
      String[] bootClasspathFiles, String[] classpathFiles) {
    List<String> result = new ArrayList<>();

    result.add(convertToTargetPath(new File(rootDir, "/bin/dalvikvm")));

    for (String option : vmOptions) {
      result.add(option);
    }
    for (Map.Entry<String, String> entry : systemProperties.entrySet()) {
      StringBuilder builder = new StringBuilder("-D");
      builder.append(entry.getKey());
      builder.append("=");
      builder.append(entry.getValue());
      result.add(builder.toString());
    }

    if (classpathFiles.length > 0) {
      result.add("-cp");
      result.add(Joiner.on(PATH_SEPARATOR_CHAR).join(
          Arrays.asList(classpathFiles).stream()
              .map(filePath -> convertToTargetPath(new File(filePath)))
              .collect(Collectors.toList())));
    }
    if (bootClasspathFiles.length > 0) {
      result.add("-Xbootclasspath:" + Joiner.on(PATH_SEPARATOR_CHAR).join(
          Arrays.asList(bootClasspathFiles).stream()
              .map(filePath -> convertToTargetPath(new File(filePath)))
              .collect(Collectors.toList())));
    }

    if (mainClass != null) {
      result.add(mainClass);
    }
    for (String argument : programArguments) {
      result.add(argument);
    }
    return result;
  }

  private void log(String message) {
    if (VERBOSE) {
      System.out.println(message);
    }
  }
}
