package replicant.spy.tools;

import elemental2.dom.DomGlobal;
import javax.annotation.Nonnull;
import org.realityforge.anodoc.Unsupported;
import replicant.Channel;
import replicant.FilterUtil;
import replicant.spy.AreaOfInterestCreatedEvent;
import replicant.spy.AreaOfInterestDisposedEvent;
import replicant.spy.AreaOfInterestUpdatedEvent;
import replicant.spy.SubscriptionCreatedEvent;
import replicant.spy.SubscriptionDisposedEvent;

/**
 * A SpyEventHandler that prints spy events to the tools console.
 * The events are colored to make them easy to digest. This class is designed to be easy to sub-class.
 */
@Unsupported( "This class relies on unstable spy API and will likely evolve as the api evolves" )
public class ConsoleSpyEventProcessor
  extends AbstractSpyEventProcessor
{
  @CssRules
  private static final String ENTITY_COLOR = "color: #CF8A3B; font-weight: normal;";
  @CssRules
  private static final String SUBSCRIPTION_COLOR = "color: #0FA13B; font-weight: normal;";
  @CssRules
  private static final String AREA_OF_INTEREST_COLOR = "color: #006AEB; font-weight: normal;";
  @CssRules
  private static final String ERROR_COLOR = "color: #A10001; font-weight: normal;";

  /**
   * Create the processor.
   */
  public ConsoleSpyEventProcessor()
  {
    on( AreaOfInterestCreatedEvent.class, this::onAreaOfInterestCreated );
    on( AreaOfInterestUpdatedEvent.class, this::onAreaOfInterestUpdated );
    on( AreaOfInterestDisposedEvent.class, this::onAreaOfInterestDisposed );

    on( SubscriptionCreatedEvent.class, this::onSubscriptionCreated );
    on( SubscriptionDisposedEvent.class, this::onSubscriptionDisposed );
  }

  /**
   * Handle the AreaOfInterestCreatedEvent.
   *
   * @param e the event.
   */
  protected void onAreaOfInterestCreated( @Nonnull final AreaOfInterestCreatedEvent e )
  {
    final Channel channel = e.getAreaOfInterest().getChannel();
    final Object filter = channel.getFilter();
    final String filterString = null == filter ? "" : " - " + FilterUtil.filterToString( filter );
    log( "%cAreaOfInterest Created " + channel.getAddress() + filterString, AREA_OF_INTEREST_COLOR );
  }

  /**
   * Handle the AreaOfInterestUpdatedEvent.
   *
   * @param e the event.
   */
  protected void onAreaOfInterestUpdated( @Nonnull final AreaOfInterestUpdatedEvent e )
  {
    final Channel channel = e.getAreaOfInterest().getChannel();
    final Object filter = channel.getFilter();
    final String filterString = FilterUtil.filterToString( filter );
    log( "%cAreaOfInterest Updated " + channel.getAddress() + " - " + filterString, AREA_OF_INTEREST_COLOR );
  }

  /**
   * Handle the AreaOfInterestDisposedEvent.
   *
   * @param e the event.
   */
  protected void onAreaOfInterestDisposed( @Nonnull final AreaOfInterestDisposedEvent e )
  {
    log( "%cAreaOfInterest Disposed " + e.getAreaOfInterest().getChannel().getAddress(), AREA_OF_INTEREST_COLOR );
  }

  /**
   * Handle the SubscriptionCreatedEvent.
   *
   * @param e the event.
   */
  protected void onSubscriptionCreated( @Nonnull final SubscriptionCreatedEvent e )
  {
    final Channel channel = e.getSubscription().getChannel();
    final Object filter = channel.getFilter();
    final String filterString = null == filter ? "" : " - " + FilterUtil.filterToString( filter );
    log( "%cSubscription Created " + channel.getAddress() + filterString, SUBSCRIPTION_COLOR );
  }

  /**
   * Handle the SubscriptionDisposedEvent.
   *
   * @param e the event.
   */
  protected void onSubscriptionDisposed( @Nonnull final SubscriptionDisposedEvent e )
  {
    log( "%cSubscription Disposed " + e.getSubscription().getChannel().getAddress(), SUBSCRIPTION_COLOR );
  }

  /**
   * Log specified message with parameters
   *
   * @param message the message.
   * @param styling the styling parameter. It is assumed that the message has a %c somewhere in it to identify the start of the styling.
   */
  protected void log( @Nonnull final String message,
                      @CssRules @Nonnull final String styling )
  {
    DomGlobal.console.log( message, styling );
  }

  /**
   * {@inheritDoc}
   */
  @Override
  protected void handleUnhandledEvent( @Nonnull final Object event )
  {
    DomGlobal.console.log( event );
  }
}

@@ -279,32 +279,87 @@
 tDisposedEvent;%0A
+import replicant.spy.AreaOfInterestStatusUpdatedEvent;%0A
 import replicant
@@ -383,32 +383,32 @@
 stUpdatedEvent;%0A
-
 import replicant
@@ -1463,32 +1463,119 @@
 erestUpdated );%0A
+    on( AreaOfInterestStatusUpdatedEvent.class, this::onAreaOfInterestStatusUpdated );%0A
     on( AreaOfIn
@@ -2630,32 +2630,32 @@
 ring( filter );%0A
-
     log( %22%25cArea
@@ -2745,32 +2745,530 @@
 T_COLOR );%0A  %7D%0A%0A
+  /**%0A   * Handle the AreaOfInterestStatusUpdatedEvent.%0A   *%0A   * @param e the event.%0A   */%0A  protected void onAreaOfInterestStatusUpdated( @Nonnull final AreaOfInterestStatusUpdatedEvent e )%0A  %7B%0A    final Channel channel = e.getAreaOfInterest().getChannel();%0A    final Object filter = channel.getFilter();%0A    final String filterString = FilterUtil.filterToString( filter );%0A    log( %22%25cAreaOfInterest Status Updated %22 + channel.getAddress() + %22 - %22 + filterString, AREA_OF_INTEREST_COLOR );%0A  %7D%0A%0A
   /**%0A   * Handl

Add console output for AreaOfInterestStatusUpdatedEvent