package org.realityforge.replicant.client.aoi;

import arez.Arez;
import arez.annotations.ArezComponent;
import arez.annotations.ComponentId;
import arez.annotations.Observable;
import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.realityforge.replicant.client.Channel;
import org.realityforge.replicant.client.ChannelAddress;
import org.realityforge.replicant.client.subscription.Subscription;

/**
 * The channel description declares a desired channel subscription and also
 * includes data on the current status of the subscription.
 */
@ArezComponent
public abstract class AreaOfInterest
{
  public enum Status
  {
    NOT_ASKED,
    LOADING,
    LOADED,
    LOAD_FAILED,
    UPDATING,
    UPDATED,
    UPDATE_FAILED,
    UNLOADING,
    UNLOADED
  }

  @Nonnull
  private final Channel _channel;
  @Nonnull
  private Status _status = Status.NOT_ASKED;
  @Nullable
  private Subscription _entry;
  @Nullable
  private Throwable _error;

  @Nonnull
  public static AreaOfInterest create( @Nonnull final Channel channel )
  {
    return new Arez_AreaOfInterest( channel );
  }

  AreaOfInterest( @Nonnull final Channel channel )
  {
    _channel = Objects.requireNonNull( channel );
  }

  @ComponentId
  @Nonnull
  public final ChannelAddress getAddress()
  {
    return getChannel().getAddress();
  }

  @Nonnull
  public Channel getChannel()
  {
    return _channel;
  }

  @Observable
  @Nonnull
  public Status getStatus()
  {
    return _status;
  }

  public void setStatus( @Nonnull final Status status )
  {
    _status = Objects.requireNonNull( status );
  }

  @Observable
  @Nullable
  public Throwable getError()
  {
    return _error;
  }

  public void setError( @Nullable final Throwable error )
  {
    _error = error;
  }

  @Observable
  @Nullable
  public Subscription getEntry()
  {
    return _entry;
  }

  public void setEntry( @Nullable final Subscription entry )
  {
    _entry = entry;
  }

  @Override
  public String toString()
  {
    if ( Arez.areNamesEnabled() )
    {
      return "AreaOfInterest[" + _channel + " Status: " + _status + "]";
    }
    else
    {
      return super.toString();
    }
  }
}

@@ -903,91 +903,8 @@
 KED;
-%0A  @Nullable%0A  private Subscription _entry;%0A  @Nullable%0A  private Throwable _error;
 %0A%0A  
@@ -1286,16 +1286,22 @@
  public 
+final 
 Channel 
@@ -1573,16 +1573,25 @@
  public 
+abstract 
 Throwabl
@@ -1606,35 +1606,9 @@
 or()
-%0A  %7B%0A    return _error;%0A  %7D
+;
 %0A%0A  
@@ -1606,32 +1606,41 @@
 or();%0A%0A  public 
+abstract 
 void setError( @
@@ -1648,22 +1648,16 @@
 ullable 
-final 
 Throwabl
@@ -1669,36 +1669,9 @@
 or )
-%0A  %7B%0A    _error = error;%0A  %7D
+;
 %0A%0A  
@@ -1703,16 +1703,25 @@
  public 
+abstract 
 Subscrip
@@ -1739,35 +1739,9 @@
 ry()
-%0A  %7B%0A    return _entry;%0A  %7D
+;
 %0A%0A  
@@ -1739,32 +1739,41 @@
 ry();%0A%0A  public 
+abstract 
 void setEntry( @
@@ -1781,22 +1781,16 @@
 ullable 
-final 
 Subscrip
@@ -1805,36 +1805,9 @@
 ry )
-%0A  %7B%0A    _entry = entry;%0A  %7D
+;
 %0A%0A  

Simplify code