// 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.synthesis.SyntheticItems.GlobalSyntheticsStrategy;
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 {
    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, GlobalSyntheticsStrategy.forNonSynthesizing())),
            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);
    }
  }
}
