/*******************************************************************************
 * Copyright (c) 2013 EclipseSource and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    EclipseSource - initial API and implementation
 ******************************************************************************/
package org.eclipse.rap.addons.autosuggest;

import static org.eclipse.rap.rwt.lifecycle.WidgetUtil.getId;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import org.eclipse.rap.addons.dropdown.DropDown;
import org.eclipse.rap.clientscripting.ClientListener;
import org.eclipse.rap.clientscripting.Script;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.internal.client.WidgetDataWhiteList;
import org.eclipse.rap.rwt.internal.client.WidgetDataWhiteListImpl;
import org.eclipse.rap.rwt.lifecycle.PhaseId;
import org.eclipse.rap.rwt.remote.Connection;
import org.eclipse.rap.rwt.remote.OperationHandler;
import org.eclipse.rap.rwt.remote.RemoteObject;
import org.eclipse.rap.rwt.testfixture.Fixture;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;


@SuppressWarnings( "restriction" )
public class AutoSuggest_Test {

  private static final String REMOTE_SELECTION_EVENT = "suggestionSelected";
  private static final String REMOTE_TYPE = "rwt.remote.Model";
  private static final String MODEL_ID_KEY = "org.eclipse.rap.addons.autosuggest#Model";

  private Text text;
  private RemoteObject remoteObject;
  private Connection connection;

  @Before
  public void setUp() {
    Fixture.setUp();
    Fixture.fakePhase( PhaseId.PROCESS_ACTION );
    Display display = new Display();
    Shell shell = new Shell( display );
    text = new Text( shell, SWT.NONE );
    mockRemoteObject();
  }

  @After
  public void tearDown() {
    Fixture.tearDown();
  }

  @Test( expected = NullPointerException.class )
  public void testConstructor_failsWithNull() {
    new AutoSuggest( null );
  }

  @Test( expected = IllegalArgumentException.class )
  public void testConstructor_failsWithDisposedText() {
    text.dispose();
    new AutoSuggest( text );
  }

  @Test
  public void testConstructor_createsDropDownWithParent() {
    AutoSuggest autoSuggest = new AutoSuggest( text );

    DropDown dropDown = autoSuggest.getDropDown();
    assertSame( text, dropDown.getParent() );
  }

  @Test
  public void testConstructor_createsRemoteObject() {
    new AutoSuggest( text );

    verify( connection ).createRemoteObject( eq( REMOTE_TYPE ) );
  }

  @Test
  public void testConstructor_addsClientListenersToText() {
    new AutoSuggest( text );

    assertTrue( text.getListeners( SWT.Verify )[ 0 ] instanceof ClientListener );
    assertTrue( text.getListeners( SWT.Modify )[ 0 ] instanceof ClientListener );
  }

  @Test
  public void testConstructor_addsClientListenersToDropDown() {
    AutoSuggest autoSuggest = new AutoSuggest( text );

    DropDown dropDown = autoSuggest.getDropDown();
    assertTrue( dropDown.getListeners( SWT.Show )[ 0 ] instanceof ClientListener );
    assertTrue( dropDown.getListeners( SWT.Hide )[ 0 ] instanceof ClientListener );
    assertTrue( dropDown.getListeners( SWT.Selection )[ 0 ] instanceof ClientListener );
    assertTrue( dropDown.getListeners( SWT.DefaultSelection )[ 0 ] instanceof ClientListener );
  }

  @Test
  public void testConstructor_setsTextIdOnModel() {
    new AutoSuggest( text );

    verify( remoteObject ).set( "textWidgetId", getId( text ) );
  }

  @Test
  public void testConstructor_setDropDownIdOnModel() {
    AutoSuggest autoSuggest = new AutoSuggest( text );

    DropDown dropDown = autoSuggest.getDropDown();
    verify( remoteObject ).set( "dropDownWidgetId", getId( dropDown ) );
  }

  @Test
  public void testConstructor_setModelIdOnDropDown() {
    AutoSuggest autoSuggest = new AutoSuggest( text );

    DropDown dropDown = autoSuggest.getDropDown();
    assertEquals( "foo", dropDown.getData( MODEL_ID_KEY ) );
  }

  @Test
  public void testConstructor_setModelIdOnText() {
    new AutoSuggest( text );

    assertEquals( "foo", text.getData( MODEL_ID_KEY ) );
  }

  @Test
  public void testConstructor_addKeysToWidgetDataWhiteList() {
    WidgetDataWhiteListImpl service
      = ( WidgetDataWhiteListImpl )RWT.getClient().getService( WidgetDataWhiteList.class );
    service.setKeys( new String[ 0 ] );

    new AutoSuggest( text );

    List<String> list = Arrays.asList( service.getKeys() );
    assertTrue( list.contains( MODEL_ID_KEY ) );
  }

  @Test
  public void testConstructor_addKeysToWidgetDataWhiteListAndKeepExistingKeys() {
    WidgetDataWhiteListImpl service
      = ( WidgetDataWhiteListImpl )RWT.getClient().getService( WidgetDataWhiteList.class );
    service.setKeys( new String[] { "foo" } );

    new AutoSuggest( text );

    List<String> list = Arrays.asList( service.getKeys() );
    assertTrue( list.contains( "foo" ) );
  }

  @Test
  public void testConstructor_addKeysToWidgetDataWhiteListOnlyOnce() {
    WidgetDataWhiteListImpl service
      = ( WidgetDataWhiteListImpl )RWT.getClient().getService( WidgetDataWhiteList.class );
    service.setKeys( new String[] { MODEL_ID_KEY } );

    new AutoSuggest( text );

    List<String> list = Arrays.asList( service.getKeys() );
    assertEquals( list.lastIndexOf( MODEL_ID_KEY ), list.indexOf( MODEL_ID_KEY ) );
  }

  @Test
  public void testConstructor_soesNotAttachListenersWithOverwrittenAttachClientListeners() {
    AutoSuggest autoSuggest = new AutoSuggest( text ) {
      @Override
      protected void attachClientListeners() {
      }
    };

    DropDown dropDown = autoSuggest.getDropDown();
    assertFalse( text.isListening( SWT.Verify ) );
    assertFalse( text.isListening( SWT.Modify ) );
    assertFalse( dropDown.isListening( SWT.Show ) );
    assertFalse( dropDown.isListening( SWT.Hide ) );
    assertFalse( dropDown.isListening( SWT.Selection ) );
    assertFalse( dropDown.isListening( SWT.DefaultSelection ) );
  }

  @Test
  public void testAttachClientListenerToText() {
    new AutoSuggest( text ) {
      @Override
      protected void attachClientListeners() {
        attachClientListenerToText( new Script( "" ), SWT.Verify, SWT.Modify );
      }
    };

    assertTrue( text.getListeners( SWT.Verify )[ 0 ] instanceof ClientListener );
    assertTrue( text.getListeners( SWT.Modify )[ 0 ] instanceof ClientListener );
  }

  @Test
  public void testAttachClientListenerToText_failsWhenCalledTwice() {
    final AtomicReference<IllegalStateException> exception = new AtomicReference<IllegalStateException>();
    new AutoSuggest( text ) {
      @Override
      protected void attachClientListeners() {
        attachClientListenerToText( new Script( "" ), SWT.Verify, SWT.Modify );
        try {
          attachClientListenerToText( new Script( "" ), SWT.Verify, SWT.Modify );
        } catch( IllegalStateException ex ) {
          exception.set( ex );
        }
      }
    };

    assertTrue( exception.get().getMessage().indexOf( "twice" ) != -1 );
  }

  @Test
  public void testAttachClientListenerToDropDown() {
    AutoSuggest autoSuggest = new AutoSuggest( text ) {
      @Override
      protected void attachClientListeners() {
        attachClientListenerToDropDown( new Script( "" ), SWT.Selection, SWT.Show );
      }
    };

    DropDown dropDown = autoSuggest.getDropDown();
    assertTrue( dropDown.getListeners( SWT.Selection )[ 0 ] instanceof ClientListener );
    assertTrue( dropDown.getListeners( SWT.Show )[ 0 ] instanceof ClientListener );
  }

  @Test
  public void testIsDisposed_returnsFalse() {
    AutoSuggest autoSuggest = new AutoSuggest( text );

    assertFalse( autoSuggest.isDisposed() );
  }

  @Test
  public void testIsDisposed_returnsTrueAfterDispose() {
    AutoSuggest autoSuggest = new AutoSuggest( text );

    autoSuggest.dispose();

    assertTrue( autoSuggest.isDisposed() );
  }

  @Test
  public void testDispose_disposesDropDown() {
    AutoSuggest autoSuggest = new AutoSuggest( text );
    DropDown dropDown = autoSuggest.getDropDown();

    autoSuggest.dispose();

    assertTrue( dropDown.isDisposed() );
  }

  @Test
  public void testDispose_destroyRemoteObject() {
    AutoSuggest autoSuggest = new AutoSuggest( text );

    autoSuggest.dispose();

    verify( remoteObject ).destroy();
  }

  @Test
  public void testDispose_removesClientListenersFromText() {
    AutoSuggest autoSuggest = new AutoSuggest( text );

    autoSuggest.dispose();

    assertFalse( text.isListening( SWT.Verify ) );
    assertFalse( text.isListening( SWT.Modify ) );
  }

  @Test
  public void testDispose_removesCustomClientListenersFromText() {
    AutoSuggest autoSuggest = new AutoSuggest( text ) {
      @Override
      protected void attachClientListeners() {
        attachClientListenerToText( new Script( "" ), SWT.Verify, SWT.FocusIn );
      }
    };

    autoSuggest.dispose();

    assertFalse( text.isListening( SWT.Verify ) );
    assertFalse( text.isListening( SWT.FocusIn ) );
  }


  @Test
  public void testDispose_disposeTwice() {
    AutoSuggest autoSuggest = new AutoSuggest( text );

    autoSuggest.dispose();
    autoSuggest.dispose();
  }


  @Test
  public void testDisposedOnTextDispose() {
    AutoSuggest autoSuggest = new AutoSuggest( text );

    text.dispose();

    assertTrue( autoSuggest.isDisposed() );
  }

  @Test
  public void testSetVisibleItemCount_setsDropDownVisibleItemCount() {
    AutoSuggest autoSuggest = new AutoSuggest( text );
    DropDown dropDown = autoSuggest.getDropDown();

    autoSuggest.setVisibleItemCount( 23 );

    assertEquals( 23, dropDown.getVisibleItemCount() );
  }

  @Test( expected = IllegalStateException.class )
  public void testSetVisibleItemCount_failsIfDisposed() {
    AutoSuggest autoSuggest = new AutoSuggest( text );
    autoSuggest.dispose();

    autoSuggest.setVisibleItemCount( 23 );
  }

  @Test
  public void testGetVisibleItemCount_getsDropDownVisibleItemCount() {
    AutoSuggest autoSuggest = new AutoSuggest( text );
    DropDown dropDown = autoSuggest.getDropDown();

    dropDown.setVisibleItemCount( 23 );

    assertEquals( 23, autoSuggest.getVisibleItemCount() );
  }

  @Test( expected = IllegalStateException.class )
  public void testGetVisibleItemCount_failsIfDisposed() {
    AutoSuggest autoSuggest = new AutoSuggest( text );
    autoSuggest.dispose();

    autoSuggest.getVisibleItemCount();
  }

  @Test
  public void testSetDataSource_acceptsNullArgument() {
    AutoSuggest autoSuggest = new AutoSuggest( text );

    autoSuggest.setDataSource( null );

    verify( remoteObject ).set( eq( "dataSourceId" ), ( String )isNull() );
  }

  @Test( expected = IllegalStateException.class )
  public void testSetDataSource_failsIfDisposed() {
    AutoSuggest autoSuggest = new AutoSuggest( text );
    autoSuggest.dispose();

    autoSuggest.setDataSource( mock( DataSource.class ) );
  }

  @Test
  public void testSetDataSource_setsDataSourceOnRemoteObject() {
    AutoSuggest autoSuggest = new AutoSuggest( text );
    DataSource dataSource = mock( DataSource.class );
    when( dataSource.getId() ).thenReturn( "providerId" );

    autoSuggest.setDataSource( dataSource );

    verify( remoteObject ).set( eq( "dataSourceId" ), eq( "providerId" ) );
  }

  @Test
  public void testSetDataSource_setsColumnWidthOnDropDown() {
    AutoSuggest autoSuggest = new AutoSuggest( text );
    DataSource dataSource = new DataSource();
    dataSource.setTemplate( new ColumnTemplate( 23, 42 ) );

    autoSuggest.setDataSource( dataSource );

    int[] columns = ( int[] )autoSuggest.getDropDown().getData( "columns" );
    assertArrayEquals( new int[] { 23, 42 }, columns );
  }

  @Test
  public void testSetAutoComplete_defaultIsNotSet() {
    new AutoSuggest( text );

    verify( remoteObject, never() ).set( eq( "autoComplete" ), anyBoolean() );
  }

  @Test( expected = IllegalStateException.class )
  public void testSetAutoComplete_failsIfDisposed() {
    AutoSuggest autoSuggest = new AutoSuggest( text );
    autoSuggest.dispose();

    autoSuggest.setAutoComplete( true );
  }

  @Test
  public void testSetAutoComplete_setsAutoCompleteTrueOnRemoteObject() {
    AutoSuggest autoSuggest = new AutoSuggest( text );

    autoSuggest.setAutoComplete( true );

    verify( remoteObject ).set( eq( "autoComplete" ), eq( true ) );
  }

  @Test
  public void testSetAutoComplete_setsAutoCompleteFalseOnRemoteObject() {
    AutoSuggest autoSuggest = new AutoSuggest( text );

    autoSuggest.setAutoComplete( false );

    verify( remoteObject ).set( eq( "autoComplete" ), eq( false ) );
  }

  @Test( expected = NullPointerException.class )
  public void testAddSelectionListener_failsWithNull() {
    AutoSuggest autoSuggest = new AutoSuggest( text );

    autoSuggest.addSelectionListener( null );
  }

  @Test( expected = IllegalStateException.class )
  public void testAddSelectionListener_failsIfDisposed() {
    AutoSuggest autoSuggest = new AutoSuggest( text );
    autoSuggest.dispose();

    autoSuggest.addSelectionListener( mock( SuggestionSelectedListener.class ) );
  }

  @Test
  public void testAddSelectionListener_doesNotAddListenerTwice() {
    AutoSuggest autoSuggest = new AutoSuggest( text );
    SuggestionSelectedListener listener = mock( SuggestionSelectedListener.class );

    autoSuggest.addSelectionListener( listener );
    autoSuggest.addSelectionListener( listener );

    autoSuggest.notifySelectionListeners();
    verify( listener, times( 1 ) ).suggestionSelected();
  }

  @Test
  public void testAddSelectionListener_callsListenOnRemoteObject() {
    AutoSuggest autoSuggest = new AutoSuggest( text );

    autoSuggest.addSelectionListener( mock( SuggestionSelectedListener.class ) );

    verify( remoteObject ).listen( REMOTE_SELECTION_EVENT, true );
  }

  @Test
  public void testAddSelectionListener_callsListenOnRemoteObjectOnlyOnce() {
    AutoSuggest autoSuggest = new AutoSuggest( text );

    autoSuggest.addSelectionListener( mock( SuggestionSelectedListener.class ) );
    autoSuggest.addSelectionListener( mock( SuggestionSelectedListener.class ) );

    verify( remoteObject, times( 1 ) ).listen( REMOTE_SELECTION_EVENT, true );
  }

  @Test
  public void testRemoveSelectionListener() {
    AutoSuggest autoSuggest = new AutoSuggest( text );
    SuggestionSelectedListener listener = mock( SuggestionSelectedListener.class );
    autoSuggest.addSelectionListener( listener );

    autoSuggest.removeSelectionListener( listener );

    autoSuggest.notifySelectionListeners();
    verify( listener, never() ).suggestionSelected();
  }

  @Test( expected = NullPointerException.class )
  public void testRemoveSelectionListener_failsWithNull() {
    AutoSuggest autoSuggest = new AutoSuggest( text );

    autoSuggest.removeSelectionListener( null );
  }

  @Test( expected = IllegalStateException.class )
  public void testRemoveSelectionListener_failsIfDispose() {
    AutoSuggest autoSuggest = new AutoSuggest( text );
    autoSuggest.dispose();

    autoSuggest.removeSelectionListener( mock( SuggestionSelectedListener.class ) );
  }

  @Test
  public void testRemoveSelectionListener_doesNotFailWithUnknownListener() {
    AutoSuggest autoSuggest = new AutoSuggest( text );
    SuggestionSelectedListener listener = mock( SuggestionSelectedListener.class );

    autoSuggest.removeSelectionListener( listener );
  }

  @Test
  public void testRemoveSelectionListener_callsListenOnRemoteObject() {
    AutoSuggest autoSuggest = new AutoSuggest( text );
    SuggestionSelectedListener listener = mock( SuggestionSelectedListener.class );
    autoSuggest.addSelectionListener( listener );

    autoSuggest.removeSelectionListener( listener );

    verify( remoteObject ).listen( REMOTE_SELECTION_EVENT, false );
  }

  @Test
  public void testRemoveSelectionListener_callsListenOnRemoteObjectOnlyForLastListener() {
    AutoSuggest autoSuggest = new AutoSuggest( text );
    SuggestionSelectedListener listener = mock( SuggestionSelectedListener.class );
    autoSuggest.addSelectionListener( mock( SuggestionSelectedListener.class ) );
    autoSuggest.addSelectionListener( listener );

    autoSuggest.removeSelectionListener( listener );

    verify( remoteObject, never() ).listen( REMOTE_SELECTION_EVENT, false );
  }

  @Test
  public void testNotifySelectionListeners_notifiesSelectionListener() {
    AutoSuggest autoSuggest = new AutoSuggest( text );
    SuggestionSelectedListener listener = mock( SuggestionSelectedListener.class );

    autoSuggest.addSelectionListener( listener );

    autoSuggest.notifySelectionListeners();
    verify( listener ).suggestionSelected();
  }

  @Test
  public void testNotifySelectionListeners_notifiesMultipleSelectionListener() {
    AutoSuggest autoSuggest = new AutoSuggest( text );
    SuggestionSelectedListener listener1 = mock( SuggestionSelectedListener.class );
    SuggestionSelectedListener listener2 = mock( SuggestionSelectedListener.class );

    autoSuggest.addSelectionListener( listener1 );
    autoSuggest.addSelectionListener( listener2 );

    autoSuggest.notifySelectionListeners();
    verify( listener1 ).suggestionSelected();
    verify( listener2 ).suggestionSelected();
  }

  @Test
  public void testNotifySelectionListeners_calledOnNotifyOperation() {
    AtomicReference<OperationHandler> operationHandlerCaptor = captureOperationHandler();
    AutoSuggest autoSuggest = new AutoSuggest( text );
    SuggestionSelectedListener listener = mock( SuggestionSelectedListener.class );
    autoSuggest.addSelectionListener( listener );

    operationHandlerCaptor.get().handleNotify( REMOTE_SELECTION_EVENT, null );

    verify( listener ).suggestionSelected();
  }

  private AtomicReference<OperationHandler> captureOperationHandler() {
    final AtomicReference<OperationHandler> captor = new AtomicReference<OperationHandler>();
    doAnswer( new Answer<Object>() {
      public Object answer( InvocationOnMock invocation ) throws Throwable {
        captor.set( ( OperationHandler )invocation.getArguments()[ 0 ] );
        return null;
      }
    } ).when( remoteObject ).setHandler( any( OperationHandler.class ) );
    return captor;
  }

  private void mockRemoteObject() {
    remoteObject = mock( RemoteObject.class );
    when( remoteObject.getId() ).thenReturn( "foo" );
    connection = spy( RWT.getUISession().getConnection() );
    when( connection.createRemoteObject( REMOTE_TYPE ) ).thenReturn( remoteObject );
    Fixture.fakeConnection( connection );
  }

}
