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

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import com.android.tools.r8.debug.DebugTestBase.JUnit3Wrapper.DebuggeeState;
import com.android.tools.r8.debug.DebugTestBase.JUnit3Wrapper.FrameInspector;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.Pair;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.StringUtils.BraceType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.harmony.jpda.tests.framework.jdwp.Frame.Variable;

public class DebugStreamComparator {

  public static class PrintOptions {
    boolean printStates = false;
    boolean printClass = false;
    boolean printMethod = false;
    boolean printVariables = false;
    boolean printStack = false;

    public static PrintOptions printAll() {
      PrintOptions options = new PrintOptions();
      options.printStates = true;
      options.printClass = true;
      options.printMethod = true;
      options.printVariables = true;
      options.printStack = true;
      return options;
    }
  }

  private boolean verifyLines = true;
  private boolean verifyFiles = true;
  private boolean verifyMethods = true;
  private boolean verifyClasses = true;
  private boolean verifyVariables = true;
  private boolean verifyStack = false;

  private Predicate<DebuggeeState> filter = s -> true;

  private final List<String> names = new ArrayList<>();
  private final List<Stream<DebuggeeState>> streams = new ArrayList<>();

  private final PrintOptions printOptions = new PrintOptions();
  private final PrintOptions errorPrintOptions = PrintOptions.printAll();

  public DebugStreamComparator add(String name, Stream<DebuggeeState> stream) {
    names.add(name);
    streams.add(stream);
    return this;
  }

  public DebugStreamComparator setFilter(Predicate<DebuggeeState> filter) {
    this.filter = filter;
    return this;
  }

  public DebugStreamComparator setVerifyLines(boolean verifyLines) {
    this.verifyLines = verifyLines;
    return this;
  }

  public DebugStreamComparator setVerifyFiles(boolean verifyFiles) {
    this.verifyFiles = verifyFiles;
    return this;
  }

  public DebugStreamComparator setVerifyMethods(boolean verifyMethods) {
    this.verifyMethods = verifyMethods;
    return this;
  }

  public DebugStreamComparator setVerifyClasses(boolean verifyClasses) {
    this.verifyClasses = verifyClasses;
    return this;
  }

  public DebugStreamComparator setVerifyVariables(boolean verifyVariables) {
    this.verifyVariables = verifyVariables;
    return this;
  }

  public DebugStreamComparator setVerifyStack(boolean verifyStack) {
    this.verifyStack = verifyStack;
    return this;
  }

  public DebugStreamComparator setPrintStates(boolean printStates) {
    printOptions.printStates = printStates;
    return this;
  }

  public DebugStreamComparator setPrintClass(boolean printClass) {
    printOptions.printClass = printClass;
    return this;
  }

  public DebugStreamComparator setPrintMethod(boolean printMethod) {
    printOptions.printMethod = printMethod;
    return this;
  }

  public DebugStreamComparator setPrintStack(boolean printStack) {
    printOptions.printStack = printStack;
    return this;
  }

  public DebugStreamComparator setPrintVariables(boolean printVariables) {
    printOptions.printVariables = printVariables;
    return this;
  }

  public void run() {
    if (streams.size() != 1) {
      throw new RuntimeException("Expected single stream to run");
    }
    internal();
  }

  public void compare() {
    if (streams.size() < 2) {
      throw new RuntimeException("Expected multiple streams to compare");
    }
    internal();
  }

  private void internal() {
    List<Iterator<DebuggeeState>> iterators =
        streams.stream().map(Stream::iterator).collect(Collectors.toList());
    while (true) {
      List<DebuggeeState> states = new ArrayList<>(iterators.size());
      boolean done = false;
      for (Iterator<DebuggeeState> iterator : iterators) {
        DebuggeeState state = iterator.next();
        states.add(state);
        if (state == null) {
          done = true;
        }
      }
      try {
        if (done) {
          assertTrue(
              "Not all streams completed at the same time",
              states.stream().allMatch(Objects::isNull));
          return;
        } else {
          if (filter.test(states.get(0))) {
            verifyStatesEqual(states);
            if (printOptions.printStates) {
              System.out.println(prettyPrintState(states.get(0), printOptions));
            }
          }
        }
      } catch (AssertionError e) {
        for (int i = 0; i < names.size(); i++) {
          System.err.println(
              names.get(i) + ":\n" + prettyPrintState(states.get(i), errorPrintOptions));
        }
        throw e;
      }
    }
  }

  public static String prettyPrintState(DebuggeeState state, PrintOptions options) {
    StringBuilder builder = new StringBuilder();
    if (!options.printStack) {
      builder.append(prettyPrintFrame(state, options));
    } else {
      for (int i = 0; i < state.getFrameDepth(); i++) {
        builder.append("f").append(i).append(": ");
        builder.append(prettyPrintFrame(state.getFrame(i), options));
        builder.append('\n');
      }
    }
    return builder.toString();
  }

  public static String prettyPrintFrame(FrameInspector frame, PrintOptions options) {
    StringBuilder builder =
        new StringBuilder()
            .append(frame.getSourceFile())
            .append(':')
            .append(frame.getLineNumber())
            .append(' ');
    if (options.printClass) {
      builder.append("\n    class:  ").append(frame.getClassName());
    }
    if (options.printMethod) {
      builder
          .append("\n    method: ")
          .append(frame.getMethodName())
          .append(frame.getMethodSignature());
    }
    if (options.printVariables) {
      builder.append(prettyPrintVariables(frame.getVisibleVariables(), options));
    }
    return builder.toString();
  }

  public static String prettyPrintVariables(List<Variable> variables, PrintOptions options) {
    StringBuilder builder = new StringBuilder("\n    locals: ");
    StringUtils.append(
        builder,
        ListUtils.map(variables, v -> v.getName() + ':' + v.getSignature()),
        ", ",
        BraceType.NONE);
    return builder.toString();
  }

  private void verifyStatesEqual(List<DebuggeeState> states) {
    DebuggeeState reference = states.get(0);
    int line = reference.getLineNumber();
    String file = reference.getSourceFile();
    String clazz = reference.getClassName();
    String method = reference.getMethodName();
    String sig = reference.getMethodSignature();
    List<Variable> variables = reference.getVisibleVariables();
    int frameDepth = reference.getFrameDepth();
    for (int i = 1; i < states.size(); i++) {
      DebuggeeState state = states.get(i);
      if (verifyFiles) {
        assertEquals("source file mismatch", file, state.getSourceFile());
      }
      if (verifyLines) {
        assertEquals("line number mismatch", line, state.getLineNumber());
      }
      if (verifyClasses) {
        assertEquals("class name mismatch", clazz, state.getClassName());
      }
      if (verifyMethods) {
        assertEquals(
            "method mismatch", method + sig, state.getMethodName() + state.getMethodSignature());
      }
      if (verifyVariables) {
        verifyVariablesEqual(variables, state.getVisibleVariables());
      }
      if (verifyStack) {
        assertEquals(frameDepth, state.getFrameDepth());
        for (int j = 0; j < frameDepth; j++) {
          FrameInspector referenceInspector = reference.getFrame(j);
          FrameInspector stateInspector = state.getFrame(j);
          verifyVariablesEqual(
              referenceInspector.getVisibleVariables(), stateInspector.getVisibleVariables());
        }
      }
    }
  }

  private static void verifyVariablesEqual(List<Variable> xs, List<Variable> ys) {
    Map<String, Variable> map = new HashMap<>(xs.size());
    for (Variable x : xs) {
      map.put(x.getName(), x);
    }
    List<Variable> unexpected = new ArrayList<>(ys.size());
    List<Pair<Variable, Variable>> different = new ArrayList<>(Math.min(xs.size(), ys.size()));
    for (Variable y : ys) {
      Variable x = map.remove(y.getName());
      if (x == null) {
        unexpected.add(y);
      } else if (!isVariableEqual(x, y)) {
        different.add(new Pair<>(x, y));
      }
    }
    StringBuilder builder = null;
    if (!map.isEmpty() || !unexpected.isEmpty()) {
      builder = new StringBuilder();
      if (!map.isEmpty()) {
        builder.append("Missing variables: ");
        for (Variable variable : map.values()) {
          builder.append(variable.getName()).append(", ");
        }
      }
      if (!unexpected.isEmpty()) {
        builder.append("Unexpected variables: ");
        for (Variable variable : unexpected) {
          builder.append(variable.getName()).append(", ");
        }
      }
    }
    if (!different.isEmpty()) {
      if (builder == null) {
        builder = new StringBuilder();
      }
      builder.append("Different variables: ");
      for (Pair<Variable, Variable> pair : different) {
        Variable x = pair.getFirst();
        Variable y = pair.getSecond();
        builder.append(x.getName()).append(":").append(x.getType());
        if (x.getGenericSignature() != null) {
          builder.append('(').append(x.getGenericSignature()).append(')');
        }
        builder.append(" != ");
        builder.append(y.getName()).append(":").append(y.getType());
        if (y.getGenericSignature() != null) {
          builder.append('(').append(y.getGenericSignature()).append(')');
        }
      }
    }
    if (builder != null) {
      fail(builder.toString());
    }
  }

  private static boolean isVariableEqual(Variable x, Variable y) {
    return x.getName().equals(y.getName())
        && x.getType().equals(y.getType())
        && Objects.equals(x.getGenericSignature(), y.getGenericSignature());
  }
}
