// 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.bisect;

import com.android.tools.r8.OutputMode;
import com.android.tools.r8.ProgramConsumer;
import com.android.tools.r8.StringConsumer;
import com.android.tools.r8.bisect.BisectOptions.Result;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.dex.ApplicationWriter;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.AndroidAppConsumers;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.ImmutableList;
import com.google.common.io.CharStreams;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Bisect {

  private final BisectOptions options;
  private final Timing timing = new Timing("bisect");

  public interface Command {

    Result apply(DexApplication application) throws Exception;
  }

  private static class StreamReader implements Runnable {

    private final InputStream stream;
    private String result;

    public StreamReader(InputStream stream) {
      this.stream = stream;
    }

    public String getResult() {
      return result;
    }

    @Override
    public void run() {
      try {
        result = CharStreams.toString(new InputStreamReader(stream, StandardCharsets.UTF_8));
        stream.close();
      } catch (IOException e) {
        result = "Failed reading result for stream " + stream;
      }
    }
  }

  public Bisect(BisectOptions options) {
    this.options = options;
  }

  public static DexProgramClass run(BisectState state, Command command, Path output,
      ExecutorService executor)
      throws Exception {
    while (true) {
      DexApplication app = state.bisect();
      state.write();
      if (app == null) {
        return state.getFinalClass();
      }
      if (command == null) {
        writeApp(app, output, executor);
        System.out.println("Bisecting completed with build in " + output + "/");
        System.out.println("Continue bisection by passing either --"
            + BisectOptions.RESULT_GOOD_FLAG + " or --"
            + BisectOptions.RESULT_BAD_FLAG);
        return null;
      }
      state.setPreviousResult(command.apply(app));
    }
  }

  public DexProgramClass run() throws Exception {
    // Setup output directory (or write to a temp dir).
    Path output;
    if (options.output != null) {
      output = options.output;
    } else {
      output = Files.createTempDirectory("bisect");
    }

    ExecutorService executor = Executors.newWorkStealingPool();
    try {
      InternalOptions internal = new InternalOptions();
      DexApplication goodApp = readApp(options.goodBuild, internal, executor);
      DexApplication badApp = readApp(options.badBuild, internal, executor);

      Path stateFile =
          options.stateFile != null ? options.stateFile : output.resolve("bisect.state");

      // Setup initial (or saved) bisection state.
      BisectState state = new BisectState(goodApp, badApp, stateFile);
      if (options.stateFile != null) {
        state.read();
      }

      // If a "previous" result is supplied on the command line, record it.
      if (options.result != Result.UNKNOWN) {
        state.setPreviousResult(options.result);
      }

      // Setup post-build command.
      Command command = null;
      if (options.command != null) {
        command =
            (application) -> {
              writeApp(application, output, executor);
              return runCommand(options.command, options.goodBuild, options.badBuild, output);
            };
      }

      // Run bisection.
      return run(state, command, output, executor);
    } finally {
      executor.shutdown();
    }
  }

  private static Result runCommand(Path command, Path good, Path bad, Path output)
      throws IOException {
    List<String> args = new ArrayList<>();
    args.add("/bin/bash");
    args.add(command.toString());
    args.addAll(ImmutableList.of(good.toString(), bad.toString(), output.toString()));
    System.out.println("Running cmd: " + String.join(" ", args));
    ProcessBuilder builder = new ProcessBuilder(args);
    Process process = builder.start();
    StreamReader stdoutReader = new StreamReader(process.getInputStream());
    StreamReader stderrReader = new StreamReader(process.getErrorStream());
    Thread stdoutThread = new Thread(stdoutReader);
    Thread stderrThread = new Thread(stderrReader);
    stdoutThread.start();
    stderrThread.start();
    try {
      process.waitFor();
      stdoutThread.join();
      stderrThread.join();
    } catch (InterruptedException e) {
      throw new RuntimeException("Execution interrupted", e);
    }
    System.out.print("OUT:\n" + stdoutReader.getResult());
    System.out.print("ERR:\n" + stderrReader.getResult());
    int result = process.exitValue();
    if (result == 0) {
      return Result.GOOD;
    } else if (result == 1) {
      return Result.BAD;
    }
    System.out.println("Failed to run command " + args);
    System.out.println("Exit code: " + result + " (expected 0 for good, 1 for bad)");
    throw new CompilationError("Failed to run command " + args);
  }

  private DexApplication readApp(Path apk, InternalOptions options, ExecutorService executor)
      throws IOException, ExecutionException {
    AndroidApp app = AndroidApp.builder().addProgramFiles(apk).build();
    return new ApplicationReader(app, options, timing).read(executor);
  }

  private static void writeApp(DexApplication app, Path output, ExecutorService executor)
      throws IOException, ExecutionException {
    InternalOptions options = app.options;
    // Save the original consumers so they can be unwrapped after write.
    ProgramConsumer programConsumer = options.programConsumer;
    StringConsumer proguardMapConsumer = options.proguardMapConsumer;
    AndroidAppConsumers compatSink = new AndroidAppConsumers(options);
    ApplicationWriter writer =
        new ApplicationWriter(
            AppView.createForD8(AppInfo.createInitialAppInfo(app)),
            null,
            GraphLens.getIdentityLens(),
            InitClassLens.getThrowingInstance(),
            NamingLens.getIdentityLens(),
            null);
    writer.write(executor);
    options.signalFinishedToConsumers();
    compatSink.build().writeToDirectory(output, OutputMode.DexIndexed);
    // Restore original consumers.
    options.programConsumer = programConsumer;
    options.proguardMapConsumer = proguardMapConsumer;
  }

  public static DexProgramClass run(BisectOptions options) throws Exception {
    return new Bisect(options).run();
  }

  public static void main(String[] args) throws Exception {
    BisectOptions options;
    try {
      options = BisectOptions.parse(args);
    } catch (CompilationError e) {
      System.err.println(e.getMessage());
      BisectOptions.printHelp(System.err);
      return;
    }
    if (options == null) {
      return;
    }
    DexProgramClass clazz = Bisect.run(options);
    if (clazz != null) {
      System.out.println("Bisection found final bad class " + clazz);
    }
  }
}
