package com.codeaffine.extras.jdt.internal.junitstatus;

import static com.codeaffine.extras.jdt.internal.prefs.PreferencePropertyTester.PROP_IS_TRUE;
import static com.codeaffine.extras.jdt.internal.prefs.WorkspaceScopePreferences.PREF_SHOW_JUNIT_STATUS_BAR;
import static org.assertj.core.api.Assertions.assertThat;

import java.util.Collection;

import org.junit.Test;

import com.codeaffine.eclipse.core.runtime.Extension;
import com.codeaffine.eclipse.core.runtime.Predicate;
import com.codeaffine.eclipse.core.runtime.RegistryAdapter;

public class JUnitStatusContributionItemPDETest {

  private static final String LOCATION
    = "toolbar:org.eclipse.ui.trim.status";

  @Test
  public void testExtension() {
    Extension extension = new RegistryAdapter()
      .readExtension( "org.eclipse.ui.menus" )
      .thatMatches( new LocationUriPredicate() )
      .process();

    Extension toolbarElement = getToolBarElement( extension );
    Extension controlElement = getControlElement( extension );
    Extension visibleWhenElement = getVisibleWhenElement( extension );
    Extension visibleTestElement = getVisibleTestElement( extension );
    assertThat( extension.getChildren( "toolbar" ) ).hasSize( 1 );
    assertThat( toolbarElement.getChildren( "control" ) ).hasSize( 1 );
    assertThat( toolbarElement.getAttribute( "label" ) ).isEqualTo( "JUnit" );
    assertThat( controlElement.getAttribute( "id" ) ).isNotNull();
    assertThat( controlElement.createExecutableExtension( JUnitStatusContributionItem.class ) ).isNotNull();
    assertThat( visibleWhenElement.getAttribute( "checkEnabled" ) ).isEqualTo( "false" );
    assertThat( visibleTestElement.getAttribute( "args" ) ).isEqualTo( PREF_SHOW_JUNIT_STATUS_BAR );
    assertThat( visibleTestElement.getAttribute( "forcePluginActivation" ) ).isEqualTo( "true" );
    assertThat( visibleTestElement.getAttribute( "property" ) ).isEqualTo( PROP_IS_TRUE );
    assertThat( visibleTestElement.getAttribute( "value" ) ).isEqualTo( "true" );
  }

  private static Extension getControlElement( Extension extension ) {
    return getFirst( getToolBarElement( extension ).getChildren( "control" ) );
  }

  private static Extension getToolBarElement( Extension extension ) {
    return getFirst( extension.getChildren( "toolbar" ) );
  }

  private static Extension getVisibleWhenElement( Extension extension ) {
    return getFirst( getControlElement( extension ).getChildren( "visibleWhen" ) );
  }

  private static Extension getVisibleTestElement( Extension extension ) {
    Extension withElement = getFirst( getVisibleWhenElement( extension ).getChildren( "with" ) );
    return getFirst( withElement.getChildren( "test" ) );
  }

  private static <T> T getFirst( Collection<T> collection ) {
    return collection.stream().findFirst().orElse( null );
  }

  private static class LocationUriPredicate implements Predicate {
    @Override
    public boolean apply( Extension input ) {
      String attribute = input.getAttribute( "locationURI" );
      return LOCATION.equals( attribute );
    }
  }
}

@@ -624,20 +624,16 @@
 LOCATION
-%0A   
  = %22tool
@@ -664,16 +664,117 @@
 status%22;
+%0A  private static final String TOOL_BAR_ID = %22com.codeaffine.extras.jdt.internal.JUnitStatusToolBar%22;
 %0A%0A  @Tes
@@ -926,27 +926,30 @@
 es( new 
-LocationUri
+JUnitStatusBar
 Predicat
@@ -2942,19 +2942,22 @@
 ass 
-LocationUri
+JUnitStatusBar
 Pred
@@ -3055,32 +3055,202 @@
     
-String attribute = input
+return isToolBarContribution( input ) && containsJUnitSttausBar( input );%0A    %7D%0A%0A    private static boolean isToolBarContribution( Extension extension ) %7B%0A      return LOCATION.equals( extension
 .get
@@ -3273,24 +3273,26 @@
 tionURI%22
+ )
  );%0A    
   return
@@ -3287,43 +3287,350 @@
     
-  return LOCATION.equals( a
+%7D%0A%0A    private static boolean containsJUnitSttausBar( Extension extension ) %7B%0A      Collection%3CExtension%3E toolBars = extension.getChildren( %22toolbar%22 );%0A      return toolBars.stream().anyMatch( element -%3E TOOL_BAR_ID.equals( getId( element ) ) );%0A    %7D%0A%0A    private static String getId( Extension element ) %7B%0A      return element.getA
 ttribute
  );%0A
@@ -3625,16 +3625,22 @@
 ttribute
+( %22id%22
  );%0A    
@@ -3645,10 +3645,11 @@
   %7D%0A  %7D%0A
+%0A
 %7D%0A

test fails when similar but unrelated extensions present