package arez.integration.dispose;

import arez.Arez;
import arez.Disposable;
import arez.annotations.ArezComponent;
import arez.annotations.CascadeDispose;
import arez.annotations.Observable;
import arez.annotations.PreDispose;
import arez.integration.AbstractArezIntegrationTest;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nonnull;
import org.realityforge.guiceyloops.shared.ValueUtil;
import org.testng.annotations.Test;
import static org.testng.Assert.*;

public class AllowWriteInDisposeIntegrationTest
  extends AbstractArezIntegrationTest
{
  @Test
  public void scenario()
  {
    final String name = ValueUtil.randomString();
    final Model1 model1 = Model1.create( name );
    final Model2 model2 = Model2.create( model1 );

    final AtomicInteger callCount = new AtomicInteger();
    Arez.context().observer( () -> {
      // Perform observation
      model1.getName();
      callCount.incrementAndGet();
    } );

    safeAction( () -> assertEquals( model1.getName(), name ) );
    assertEquals( callCount.get(), 1 );

    Disposable.dispose( model2 );

    safeAction( () -> assertEquals( model1.getName(), "X" ) );
    assertEquals( callCount.get(), 2 );
  }

  @ArezComponent
  static abstract class Model1
  {
    @Nonnull
    static Model1 create( @Nonnull final String name )
    {
      return new AllowWriteInDisposeIntegrationTest_Arez_Model1( name );
    }

    @Observable
    @Nonnull
    abstract String getName();

    abstract void setName( @Nonnull String name );
  }

  @ArezComponent
  static abstract class Model2
  {
    @CascadeDispose
    @Nonnull
    final Model1 _other;

    @Nonnull
    static Model2 create( @Nonnull final Model1 other )
    {
      return new AllowWriteInDisposeIntegrationTest_Arez_Model2( other );
    }

    Model2( @Nonnull final Model1 other )
    {
      _other = other;
    }

    @PreDispose
    final void preDispose()
    {
      _other.setName( "X" );
    }
  }
}

@@ -113,48 +113,8 @@
 nt;%0A
-import arez.annotations.CascadeDispose;%0A
 impo
@@ -1490,32 +1490,53 @@
   @ArezComponent
+( allowEmpty = true )
 %0A  static abstra
@@ -1559,28 +1559,8 @@
   %7B%0A
-    @CascadeDispose%0A
     
@@ -1568,29 +1568,31 @@
 Nonnull%0A    
-final
+private
  Model1 _oth

Revert "Cascade dispose related component"