package com.intellij.debugger.streams.trace.smart.handler;

import com.intellij.debugger.streams.wrapper.MethodCall;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Vitaliy.Bibaev
 */
public class DistinctHandler extends HandlerBase {
  private final PeekTracerHandler myPeekTracer;

  public DistinctHandler(int callNumber, @NotNull String callName) {
    myPeekTracer = new PeekTracerHandler(callNumber, callName);

  }

  @NotNull
  @Override
  public List<MethodCall> additionalCallsBefore() {
    final List<MethodCall> result = new ArrayList<>();
    // TODO: insert calls
    result.addAll(myPeekTracer.additionalCallsBefore());
    return result;
  }

  @NotNull
  @Override
  public List<MethodCall> additionalCallsAfter() {
    return myPeekTracer.additionalCallsAfter();
  }

  @NotNull
  @Override
  public String prepareResult() {
    return doPrepareResult() + myPeekTracer.prepareResult();
  }

  @NotNull
  @Override
  public String getResultExpression() {
    return null;
  }

  @NotNull
  private String doPrepareResult() {
    return "";
  }

  @NotNull
  @Override
  protected List<Variable> getVariables() {
    return null;
  }
}

@@ -181,16 +181,41 @@
 ayList;%0A
+import java.util.Arrays;%0A
 import j
@@ -362,16 +362,130 @@
 kTracer;
+%0A  private final HashMapVariableImpl myStoreMapVariable;%0A  private final HashMapVariableImpl myResolveMapVariable;
 %0A%0A  publ
@@ -618,368 +618,854 @@
 %0A%0A  
-%7D%0A%0A  @NotNull%0A  @Override%0A  public List%3CMethodCall%3E additionalCallsBefore() %7B%0A    final List%3CMethodCall%3E result = new ArrayList%3C%3E();%0A    // TODO: insert calls%0A    result.addAll(myPeekTracer.additionalCallsBefore());%0A    return result;%0A  %7D%0A%0A  @NotNull%0A  @Override%0A  public List%3CMethodCall%3E additionalCallsAfter() %7B%0A    return myPeekTracer.additionalCallsAfter()
+  final String variablePrefix = callName + callNumber;%0A    myStoreMapVariable = new HashMapVariableImpl(variablePrefix + %22Store%22, %22Object%22, %22Map%3CInteger, Object%3E%22, false);%0A    myResolveMapVariable = new HashMapVariableImpl(variablePrefix + %22Resolve%22, %22Object%22, %22Object%22, false);%0A  %7D%0A%0A  @NotNull%0A  @Override%0A  public List%3CMethodCall%3E additionalCallsBefore() %7B%0A    final List%3CMethodCall%3E result = new ArrayList%3C%3E(myPeekTracer.additionalCallsBefore());%0A%0A    final PeekCall storeCall = new PeekCall(createStoreLambda());%0A    result.add(storeCall);%0A    return result;%0A  %7D%0A%0A  @NotNull%0A  @Override%0A  public List%3CMethodCall%3E additionalCallsAfter() %7B%0A    final List%3CMethodCall%3E result = new ArrayList%3C%3E(myPeekTracer.additionalCallsAfter());%0A    final MethodCall checkCall = new PeekCall(createResolveLambda());%0A    result.add(checkCall);%0A    return result
 ;%0A  
@@ -1660,28 +1660,26 @@
 %0A    return 
-null
+%22%22
 ;%0A  %7D%0A%0A  @No
@@ -1758,77 +1758,1180 @@
 l%0A  
-@Override%0A  protected List%3CVariable%3E getVariables() %7B%0A    return null
+private String createStoreLambda() %7B%0A    final String storeMap = myStoreMapVariable.getName();%0A    return %22x -%3E %22 +%0A           String.format(%22%25s.computeIfAbsent(x, () -%3E new LinkedHashMap%3CObject%3E).put(time.get(), x)%22, storeMap);%0A  %7D%0A%0A  @NotNull%0A  private String createResolveLambda() %7B%0A    final String newLine = System.lineSeparator();%0A    final String storeMap = myStoreMapVariable.getName();%0A    final String resolveMap = myResolveMapVariable.getName();%0A%0A    return %22x -%3E %7B%22 + newLine +%0A           %22final Map%3CInteger, Object%3E objects = %22 + String.format(%22%25s.get(x);%22, storeMap) + newLine +%0A           %22for (final int key: objects) %7B%22 + newLine +%0A           %22final Object value = objects.get(key);%22 + newLine +%0A           %22if (value == x) %7B%22 + newLine +%0A           String.format(%22%25s.put(key, time.get())%22, resolveMap) + newLine +%0A           %22    %7D%22 + newLine +%0A           %22  %7D%22 + newLine +%0A           %22%7D%22 + newLine;%0A  %7D%0A%0A  @NotNull%0A  @Override%0A  protected List%3CVariable%3E getVariables() %7B%0A    final List%3CVariable%3E variables = new ArrayList%3C%3E(Arrays.asList(myStoreMapVariable, myResolveMapVariable));%0A    variables.addAll(myPeekTracer.getVariables());%0A    return variables
 ;%0A  

Implement lambdas for distinct handler to generate tracing code