// Copyright (c) 2022, 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.utils;

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.ProgramClass;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.IOException;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class DeterminismChecker {

  /**
   * Create a new checker with a directory of log files as backing
   *
   * <p>The checker must be created as a new instance for each compilation. Withing the directory
   * the respective check points will be emitted/checked via successive log files.
   */
  public static DeterminismChecker createWithFileBacking(Path directory) {
    return new DeterminismChecker(
        new LineCallbackSupplier() {
          // Index of the "checkpoint", there can be several if checked at multiple points during
          // compiler execution.
          private int index = 0;

          @Override
          public LineCallback createCallback() throws IOException {
            // This is called on each "checkpoint" and the index is bumped.
            Path log = directory.resolve("" + index++ + ".log");
            if (Files.exists(log)) {
              System.out.println("Checking against determinism log: " + log);
              return new LineCallbackChecker(Files.newBufferedReader(log, StandardCharsets.UTF_8));
            } else {
              System.out.println("Writing determinism log: " + log);
              BufferedWriter bufferedWriter =
                  Files.newBufferedWriter(
                      log,
                      StandardCharsets.UTF_8,
                      StandardOpenOption.CREATE,
                      StandardOpenOption.TRUNCATE_EXISTING);
              return new LineCallbackWriter(bufferedWriter);
            }
          }
        });
  }

  /** Supplier/factory to support multiple checkpoints. */
  public interface LineCallbackSupplier {
    LineCallback createCallback() throws IOException;
  }

  /** Interface for the write-or-check of each line. */
  public interface LineCallback extends Closeable {
    boolean onLine(String line) throws IOException;
  }

  private final LineCallbackSupplier callbackFactory;

  private DeterminismChecker(LineCallbackSupplier callbackFactory) {
    this.callbackFactory = callbackFactory;
  }

  private static String fmtClass(DexProgramClass clazz) {
    return clazz.getType().toSourceString()
        + " "
        + clazz.getMethodCollection().getBackingDescriptionString();
  }

  private static String fmtMethod(DexEncodedMethod method) {
    return method.getReference().toSourceString();
  }

  public void check(AppView<?> appView) {
    try (LineCallback callback = callbackFactory.createCallback()) {
      List<DexProgramClass> classes = new ArrayList<>(appView.appInfo().classes());
      classes.sort(Comparator.comparing(ProgramClass::getType));
      for (int i = 0; i < classes.size(); i++) {
        DexProgramClass clazz = classes.get(i);
        checkClass(callback, clazz);
      }
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  private void checkClass(LineCallback callback, DexProgramClass clazz) throws IOException {
    String line = fmtClass(clazz);
    if (!callback.onLine(line)) {
      return;
    }
    for (DexEncodedMethod method : clazz.methods()) {
      checkMethod(callback, method);
    }
  }

  private void checkMethod(LineCallback callback, DexEncodedMethod method) throws IOException {
    String header = fmtMethod(method);
    if (!callback.onLine(header)) {
      return;
    }
    if (method.hasCode()) {
      String[] lines = method.getCode().toString().split("\n");
      for (String line : lines) {
        if (!callback.onLine(line)) {
          return;
        }
      }
    } else {
      if (!callback.onLine("<nocode>")) {
        return;
      }
    }
  }

  /** Shared escape function. */
  private static String escape(String line) {
    // Replace \r so the line splitting is always consistently on \n.
    return line.replace("\r", "<CR>");
  }

  /** Implementation of the checker (must be consistent with the writer). */
  private static class LineCallbackChecker implements LineCallback {

    private final BufferedReader reader;

    public LineCallbackChecker(BufferedReader reader) {
      this.reader = reader;
    }

    @Override
    public boolean onLine(String unescapedLine) throws IOException {
      String line = escape(unescapedLine);
      String dumpLine = reader.readLine();
      boolean equals = dumpLine.equals(line);
      if (!equals) {
        throw new AssertionError(
            "\nMismatch for line: " + line + "\n" + "    and dump-line: " + dumpLine);
      }
      return equals;
    }

    @Override
    public void close() throws IOException {
      reader.close();
    }
  }

  /** Implementation of the writer (must be consistent with the checker). */
  private static class LineCallbackWriter implements LineCallback {

    private final Writer writer;

    public LineCallbackWriter(Writer writer) {
      this.writer = writer;
    }

    @Override
    public boolean onLine(String line) throws IOException {
      writer.write(escape(line));
      writer.write('\n');
      return true;
    }

    @Override
    public void close() throws IOException {
      writer.close();
    }
  }
}
