package arez.integration;

import arez.Arez;
import arez.ArezTestUtil;
import arez.Observer;
import arez.ObserverError;
import java.util.ArrayList;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.realityforge.braincheck.BrainCheckTestUtil;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import static org.testng.Assert.*;

@SuppressWarnings( "Duplicates" )
public abstract class AbstractArezIntegrationTest
{
  private final ArrayList<String> _observerErrors = new ArrayList<>();
  private boolean _ignoreObserverErrors;

  @BeforeMethod
  protected void beforeTest()
    throws Exception
  {
    BrainCheckTestUtil.resetConfig( false );
    ArezTestUtil.resetConfig( false );
    _ignoreObserverErrors = false;
    _observerErrors.clear();
    Arez.context().addObserverErrorHandler( this::onObserverError );
  }

  protected void onObserverError( @Nonnull final Observer observer,
                                  @Nonnull final ObserverError error,
                                  @Nullable final Throwable throwable )
  {
    if ( !_ignoreObserverErrors )
    {
      final String message = "Observer: " + observer.getName() + " Error: " + error + " " + throwable;
      _observerErrors.add( message );
      System.out.println( message );
    }
  }

  @AfterMethod
  protected void afterTest()
    throws Exception
  {
    BrainCheckTestUtil.resetConfig( true );
    ArezTestUtil.resetConfig( true );
    if ( !_ignoreObserverErrors && !_observerErrors.isEmpty() )
    {
      fail( "Unexpected Observer Errors: " + _observerErrors.stream().collect( Collectors.joining( "\n" ) ) );
    }
  }
}

@@ -440,16 +440,18 @@
 arnings(
+ %7B
  %22Duplic
@@ -455,16 +455,40 @@
 licates%22
+, %22SameParameterValue%22 %7D
  )%0Apubli
@@ -645,16 +645,320 @@
 rErrors;
+%0A  private boolean _printObserverErrors;%0A%0A  final void setIgnoreObserverErrors( final boolean ignoreObserverErrors )%0A  %7B%0A    _ignoreObserverErrors = ignoreObserverErrors;%0A  %7D%0A%0A  final void setPrintObserverErrors( final boolean printObserverErrors )%0A  %7B%0A    _printObserverErrors = printObserverErrors;%0A  %7D
 %0A%0A  @Bef
@@ -1141,16 +1141,49 @@
  false;%0A
+    _printObserverErrors = true;%0A
     _obs
@@ -1277,31 +1277,29 @@
 );%0A  %7D%0A%0A  pr
-otec
+iva
 te
-d
  void onObse
@@ -1375,18 +1375,16 @@
         
-  
 @Nonnull
@@ -1411,18 +1411,16 @@
  error,%0A
-  
         
@@ -1489,50 +1489,8 @@
   %7B%0A
-    if ( !_ignoreObserverErrors )%0A    %7B%0A  
     
@@ -1590,18 +1590,16 @@
 le;%0A    
-  
 _observe
@@ -1618,24 +1618,62 @@
  message );%0A
+    if ( _printObserverErrors )%0A    %7B%0A
       System
@@ -2049,11 +2049,105 @@
    %7D%0A  %7D
+%0A%0A  @Nonnull%0A  final ArrayList%3CString%3E getObserverErrors()%0A  %7B%0A    return _observerErrors;%0A  %7D
 %0A%7D%0A

Add support for inspecting the errors