package com.github.dakusui.actionunit.visitors;

import com.github.dakusui.actionunit.core.Action;
import com.github.dakusui.actionunit.core.Context;
import com.github.dakusui.actionunit.io.Writer;

import java.util.LinkedHashMap;
import java.util.Map;

import static java.util.Objects.requireNonNull;

public class ReportingActionPerformer extends ActionPerformer {
  private final Map<Action, Record> report;

  private ReportingActionPerformer() {
    this(Context.create(), new LinkedHashMap<>());
  }

  private ReportingActionPerformer(Context context, Map<Action, Record> report) {
    super(context);
    this.report = report;
  }

  @Override
  protected Action.Visitor newInstance(Context context) {
    return new ReportingActionPerformer(context, this.report);
  }

  @Override
  protected void callAccept(Action action, Action.Visitor visitor) {
    synchronized (report) {
      report.computeIfAbsent(action, a -> createRecord());
    }
    Record record = requireNonNull(report.get(action));
    record.started();
    try {
      action.accept(visitor);
      record.succeeded();
    } catch (Throwable t) {
      record.failed(t);
      throw t;
    }
  }

  public void perform(Action action) {
    callAccept(requireNonNull(action), this);
  }

  public void performAndReport(Action action, Writer writer) {
    try {
      perform(action);
    } finally {
      new ActionReporter(writer, this.getReport()).report(action);
    }
  }

  public Map<Action, Record> getReport() {
    return this.report;
  }

  protected Record createRecord() {
    return new Record();
  }

  public static ReportingActionPerformer create() {
    return new ReportingActionPerformer();
  }
}

@@ -190,16 +190,73 @@
 .Writer;
+%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;
 %0A%0Aimport
@@ -427,21 +427,137 @@
 private 
-final
+static final Logger              LOGGER = LoggerFactory.getLogger(ReportingActionPerformer.class);%0A  private final       
  Map%3CAct
@@ -1021,24 +1021,43 @@
  visitor) %7B%0A
+    Record record;%0A
     synchron
@@ -1077,16 +1077,25 @@
  %7B%0A     
+ record =
  report.
@@ -1154,59 +1154,142 @@
     
-R
+if (r
 ecord 
-record = requireNonNull(report.get(action));
+== null) %7B%0A      LOGGER.error(%22record became null for action:%7B%7D(%7B%7D)%22, action, action.getClass());%0A      assert false;%0A    %7D
 %0A   

Fix a potential NPE (issue #88)