/*
 * Copyright 2010 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.activity.shared;

import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.UmbrellaException;
import com.google.gwt.event.shared.testing.CountingEventBus;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceChangeEvent;
import com.google.gwt.place.shared.PlaceChangeRequestEvent;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Widget;

import junit.framework.TestCase;

/**
 * Eponymous unit test.
 */
public class ActivityManagerTest extends TestCase {
  private static class AsyncActivity extends SyncActivity {
    AsyncActivity(MyView view) {
      super(view);
    }

    @Override
    public void start(AcceptsOneWidget display, EventBus eventBus) {
      this.display = display;
      this.bus = eventBus;
    }

    void finish() {
      display.setWidget(view);
    }
  }

  private static class Event extends GwtEvent<Handler> {
    private static GwtEvent.Type<EventHandler> TYPE = new GwtEvent.Type<EventHandler>();

    @Override
    public GwtEvent.Type<Handler> getAssociatedType() {
      throw new UnsupportedOperationException("Auto-generated method stub");
    }

    @Override
    protected void dispatch(Handler handler) {
      throw new UnsupportedOperationException("Auto-generated method stub");
    }
  }

  private static class Handler implements EventHandler {
  };

  private static class MyDisplay implements AcceptsOneWidget {
    IsWidget widget = null;

    @Override
    public void setWidget(IsWidget widget) {
      this.widget = widget;
    }
  }

  private static class MyPlace extends Place {
  }

  private static class MyView implements IsWidget {
    @Override
    public Widget asWidget() {
      return null;
    }
  }
  private static class SyncActivity implements Activity {
    boolean canceled = false;
    boolean stopped = false;
    AcceptsOneWidget display;
    String stopWarning;
    MyView view;
    EventBus bus;

    SyncActivity(MyView view) {
      this.view = view;
    }

    @Override
    public String mayStop() {
      return stopWarning;
    }

    @Override
    public void onCancel() {
      canceled = true;
    }

    @Override
    public void onStop() {
      stopped = true;
    }

    @Override
    public void start(AcceptsOneWidget display, EventBus eventBus) {
      this.display = display;
      this.bus = eventBus;
      display.setWidget(view);
    }
  }

  private final MyPlace place1 = new MyPlace();
  private final MyPlace place2 = new MyPlace();

  private SyncActivity activity1 = new SyncActivity(new MyView());

  private SyncActivity activity2 = new SyncActivity(new MyView());

  private final MyDisplay realDisplay = new MyDisplay();
  private final ActivityMapper myMap = new ActivityMapper() {
    @Override
    public Activity getActivity(Place place) {
      if (place.equals(place1)) {
        return activity1;
      }
      if (place.equals(place2)) {
        return activity2;
      }

      return null;
    }
  };

  private CountingEventBus eventBus = new CountingEventBus();

  private ActivityManager manager = new ActivityManager(
      myMap, eventBus);

  public void testActiveEventBus() {
    final AsyncActivity asyncActivity1 = new AsyncActivity(new MyView());
    final AsyncActivity asyncActivity2 = new AsyncActivity(new MyView());

    ActivityMapper map = new ActivityMapper() {
      @Override
      public Activity getActivity(Place place) {
        if (place.equals(place1)) {
          return asyncActivity1;
        }
        if (place.equals(place2)) {
          return asyncActivity2;
        }

        return null;
      }
    };

    manager = new ActivityManager(map, eventBus);
    manager.setDisplay(realDisplay);

    eventBus.fireEvent(new PlaceChangeEvent(place1));
    com.google.web.bindery.event.shared.EventBus activeEventBus =
        manager.getActiveEventBus();
 
    activeEventBus.addHandler(Event.TYPE, new Handler());
    assertEquals(1, eventBus.getCount(Event.TYPE));

    eventBus.fireEvent(new PlaceChangeEvent(place2));
    assertEquals(0, eventBus.getCount(Event.TYPE));
  }
  
  public void testAsyncDispatch() {
    final AsyncActivity asyncActivity1 = new AsyncActivity(new MyView());
    final AsyncActivity asyncActivity2 = new AsyncActivity(new MyView());

    ActivityMapper map = new ActivityMapper() {
      @Override
      public Activity getActivity(Place place) {
        if (place.equals(place1)) {
          return asyncActivity1;
        }
        if (place.equals(place2)) {
          return asyncActivity2;
        }

        return null;
      }
    };

    manager = new ActivityManager(map, eventBus);
    manager.setDisplay(realDisplay);

    PlaceChangeRequestEvent event = new PlaceChangeRequestEvent(
        place1);
    eventBus.fireEvent(event);
    assertNull(event.getWarning());
    assertNull(realDisplay.widget);
    assertFalse(asyncActivity1.stopped);
    assertFalse(asyncActivity1.canceled);
    assertNull(asyncActivity1.display);

    eventBus.fireEvent(new PlaceChangeEvent(place1));
    assertNull(realDisplay.widget);
    assertFalse(asyncActivity1.stopped);
    assertFalse(asyncActivity1.canceled);
    assertNotNull(asyncActivity1.display);

    asyncActivity1.finish();
    assertEquals(asyncActivity1.view, realDisplay.widget);
    assertFalse(asyncActivity1.stopped);
    assertFalse(asyncActivity1.canceled);

    event = new PlaceChangeRequestEvent(place2);
    eventBus.fireEvent(event);
    assertNull(event.getWarning());
    assertEquals(asyncActivity1.view, realDisplay.widget);
    assertFalse(asyncActivity1.stopped);
    assertFalse(asyncActivity1.canceled);
    assertFalse(asyncActivity2.stopped);
    assertFalse(asyncActivity2.canceled);
    assertNull(asyncActivity2.display);

    eventBus.fireEvent(new PlaceChangeEvent(place2));
    assertNull(realDisplay.widget);
    assertFalse(asyncActivity1.canceled);
    assertTrue(asyncActivity1.stopped);
    assertFalse(asyncActivity2.stopped);
    assertFalse(asyncActivity2.canceled);
    assertNotNull(asyncActivity2.display);

    asyncActivity2.finish();
    assertEquals(asyncActivity2.view, realDisplay.widget);
  }

  public void testCancel() {
    final AsyncActivity asyncActivity1 = new AsyncActivity(new MyView());
    final AsyncActivity ayncActivity2 = new AsyncActivity(new MyView());

    ActivityMapper map = new ActivityMapper() {
      @Override
      public Activity getActivity(Place place) {
        if (place.equals(place1)) {
          return asyncActivity1;
        }
        if (place.equals(place2)) {
          return ayncActivity2;
        }

        return null;
      }
    };

    manager = new ActivityManager(map, eventBus);
    manager.setDisplay(realDisplay);

    PlaceChangeRequestEvent event = new PlaceChangeRequestEvent(
        place1);
    eventBus.fireEvent(event);
    assertNull(event.getWarning());
    assertNull(realDisplay.widget);
    assertFalse(asyncActivity1.stopped);
    assertFalse(asyncActivity1.canceled);
    assertNull(asyncActivity1.display);

    eventBus.fireEvent(new PlaceChangeEvent(place1));
    assertNull(realDisplay.widget);
    assertFalse(asyncActivity1.stopped);
    assertFalse(asyncActivity1.canceled);
    assertNotNull(asyncActivity1.display);

    event = new PlaceChangeRequestEvent(place2);
    eventBus.fireEvent(event);
    assertNull(event.getWarning());
    assertNull(realDisplay.widget);
    assertFalse(asyncActivity1.stopped);
    assertFalse(asyncActivity1.canceled);

    eventBus.fireEvent(new PlaceChangeEvent(place2));
    assertNull(realDisplay.widget);
    assertTrue(asyncActivity1.canceled);
    assertFalse(asyncActivity1.stopped);
    assertFalse(ayncActivity2.stopped);
    assertFalse(ayncActivity2.canceled);
    assertNotNull(ayncActivity2.display);

    ayncActivity2.finish();
    assertEquals(ayncActivity2.view, realDisplay.widget);

    asyncActivity1.finish();
    assertEquals(ayncActivity2.view, realDisplay.widget);
  }

  public void testDropHandlersOnStop() {
    manager.setDisplay(realDisplay);

    assertEquals(0, eventBus.getCount(Event.TYPE));

    activity1 = new SyncActivity(null) {
      @Override
      public void start(AcceptsOneWidget panel, EventBus eventBus) {
        super.start(panel, eventBus);
        bus.addHandler(Event.TYPE, new Handler());
      }

      @Override
      public void onStop() {
        super.onStop();
        bus.addHandler(Event.TYPE, new Handler());
      }
    };

    PlaceChangeEvent event = new PlaceChangeEvent(place1);
    eventBus.fireEvent(event);
    assertEquals(1, eventBus.getCount(Event.TYPE));

    event = new PlaceChangeEvent(place2);
    eventBus.fireEvent(event);
    assertEquals(0, eventBus.getCount(Event.TYPE));

    // Make sure we didn't nuke the ActivityManager's own handlers
    assertEquals(1, eventBus.getCount(PlaceChangeEvent.TYPE));
    assertEquals(1, eventBus.getCount(PlaceChangeRequestEvent.TYPE));
  }

  public void testEventSetupAndTeardown() {
    assertEquals(0, eventBus.getCount(PlaceChangeEvent.TYPE));
    assertEquals(0, eventBus.getCount(PlaceChangeRequestEvent.TYPE));

    manager.setDisplay(realDisplay);

    assertEquals(1, eventBus.getCount(PlaceChangeEvent.TYPE));
    assertEquals(1, eventBus.getCount(PlaceChangeRequestEvent.TYPE));

    manager.setDisplay(null);

    assertEquals(0, eventBus.getCount(PlaceChangeEvent.TYPE));
    assertEquals(0, eventBus.getCount(PlaceChangeRequestEvent.TYPE));
  }

  public void testExceptionsOnStartAndCancel() {
    activity1 = new AsyncActivity(null) {
      @Override
      public void start(AcceptsOneWidget panel, EventBus eventBus) {
        super.start(panel, eventBus);
        bus.addHandler(Event.TYPE, new Handler());
      }
      @Override
      public void onCancel() {
        super.onCancel();
        bus.addHandler(Event.TYPE, new Handler());
        throw new UnsupportedOperationException("Exception on cancel");
      }
    };

    activity2 = new SyncActivity(null) {
      @Override
      public void start(AcceptsOneWidget panel, EventBus eventBus) {
        super.start(panel, eventBus);
        throw new UnsupportedOperationException("Exception on start");
      }
    };

    manager.setDisplay(realDisplay);

    try {
      PlaceChangeEvent event = new PlaceChangeEvent(place1);
      eventBus.fireEvent(event);
      assertEquals(1, eventBus.getCount(Event.TYPE));

      event = new PlaceChangeEvent(place2);
      eventBus.fireEvent(event);

      fail("Expected exception");
    } catch (UmbrellaException e) {
      // EventBus throws this one
      assertEquals(1, e.getCauses().size());
      // And this is the one thrown by ActivityManager
      UmbrellaException nested = (UmbrellaException) e.getCause();
      assertEquals(2, nested.getCauses().size());
    }

    assertTrue(activity1.canceled);
    assertNotNull(activity2.display);
    assertEquals(0, eventBus.getCount(Event.TYPE));
  }
  
  public void testExceptionsOnStopAndStart() {
    activity1 = new SyncActivity(null) {
      @Override
      public void start(AcceptsOneWidget panel, EventBus eventBus) {
        super.start(panel, eventBus);
        bus.addHandler(Event.TYPE, new Handler());
      }
      @Override
      public void onStop() {
        super.onStop();
        bus.addHandler(Event.TYPE, new Handler());
        throw new UnsupportedOperationException("Exception on stop");
      }
    };

    activity2 = new SyncActivity(null) {
      @Override
      public void start(AcceptsOneWidget panel, EventBus eventBus) {
        super.start(panel, eventBus);
        throw new UnsupportedOperationException("Exception on start");
      }
    };

    manager.setDisplay(realDisplay);

    try {
      PlaceChangeEvent event = new PlaceChangeEvent(place1);
      eventBus.fireEvent(event);
      assertEquals(1, eventBus.getCount(Event.TYPE));

      event = new PlaceChangeEvent(place2);
      eventBus.fireEvent(event);

      fail("Expected exception");
    } catch (UmbrellaException e) {
      // EventBus throws this one
      assertEquals(1, e.getCauses().size());
      // And this is the one thrown by ActivityManager
      UmbrellaException nested = (UmbrellaException) e.getCause();
      assertEquals(2, nested.getCauses().size());
    }

    assertTrue(activity1.stopped);
    assertNotNull(activity2.display);
    assertEquals(0, eventBus.getCount(Event.TYPE));
  }
  
  /**
   * @see http://code.google.com/p/google-web-toolkit/issues/detail?id=5375
   */
  public void testNullDisplayOnPlaceChange() {
    manager.setDisplay(realDisplay);
    
    // Start an activity
    manager.onPlaceChange(new PlaceChangeEvent(place1));
    
    /*
     * Now we're going to place2. During PlaceChangeEvent dispatch, 
     * someone kills the manager's display.
     */
    manager.setDisplay(null);
    
    // Now the place change event reaches the manager
    manager.onPlaceChange(new PlaceChangeEvent(place2));
    
    assertNull(activity2.display);
    assertTrue(activity1.stopped);
  }
  
  public void testNullDisplayBeforeAsyncStart() {
    final AsyncActivity asyncActivity1 = new AsyncActivity(new MyView());
    final AsyncActivity asyncActivity2 = new AsyncActivity(new MyView());

    ActivityMapper map = new ActivityMapper() {
      @Override
      public Activity getActivity(Place place) {
        if (place.equals(place1)) {
          return asyncActivity1;
        }
        if (place.equals(place2)) {
          return asyncActivity2;
        }

        return null;
      }
    };

    manager = new ActivityManager(map, eventBus);
    manager.setDisplay(realDisplay);
    
    // Start an activity
    manager.onPlaceChange(new PlaceChangeEvent(place1));

    // Kill the manager
    manager.setDisplay(null);
    
    // The activity is ready to play
    asyncActivity1.finish();
    
    // Ta da, no NPE
  }

  public void testRejected() {
    manager.setDisplay(realDisplay);

    activity1.stopWarning = "Stop fool!";

    PlaceChangeRequestEvent event = new PlaceChangeRequestEvent(
        place1);
    eventBus.fireEvent(event);
    assertNull(event.getWarning());
    assertNull(realDisplay.widget);

    eventBus.fireEvent(new PlaceChangeEvent(place1));
    assertEquals(activity1.view, realDisplay.widget);

    event = new PlaceChangeRequestEvent(place2);
    eventBus.fireEvent(event);
    assertEquals(activity1.stopWarning, event.getWarning());
    assertEquals(activity1.view, realDisplay.widget);
    assertFalse(activity1.stopped);
    assertFalse(activity1.canceled);
  }

  public void testSyncDispatch() {
    manager.setDisplay(realDisplay);

    PlaceChangeRequestEvent event = new PlaceChangeRequestEvent(
        place1);
    eventBus.fireEvent(event);
    assertNull(event.getWarning());
    assertNull(realDisplay.widget);
    assertFalse(activity1.stopped);
    assertFalse(activity1.canceled);

    eventBus.fireEvent(new PlaceChangeEvent(place1));
    assertEquals(activity1.view, realDisplay.widget);
    assertFalse(activity1.stopped);
    assertFalse(activity1.canceled);

    event = new PlaceChangeRequestEvent(place2);
    eventBus.fireEvent(event);
    assertNull(event.getWarning());
    assertEquals(activity1.view, realDisplay.widget);
    assertFalse(activity1.stopped);
    assertFalse(activity1.canceled);

    eventBus.fireEvent(new PlaceChangeEvent(place2));
    assertEquals(activity2.view, realDisplay.widget);
    assertTrue(activity1.stopped);
    assertFalse(activity1.canceled);
  }
  
  /**
   * Non-regression test: make sure an activity can call {@link AcceptsOneWidget#setWidget(IsWidget)} several times to switch views.
   */
  public void testSetWidgetSeveralTimesPerActivity() {
    class TwoViewActivity extends SyncActivity {
      MyView view2;
      
      public TwoViewActivity(MyView view1, MyView view2) {
        super(view1);
        this.view2 = view2;
      }
      
      void secondView() {
        display.setWidget(view2);
      }
      
      void firstView() {
        display.setWidget(view);
      }
    }
    final TwoViewActivity activity = new TwoViewActivity(new MyView(), new MyView());
    
    ActivityMapper map = new ActivityMapper() {
      @Override
      public Activity getActivity(Place place) {
        return activity;
      }
    };

    manager = new ActivityManager(map, eventBus);
    manager.setDisplay(realDisplay);
    
    // Start an activity
    manager.onPlaceChange(new PlaceChangeEvent(place1));

    assertEquals(activity.view, realDisplay.widget);
    
    // Call setWidget on the display several times, just to make sure it's possible
    activity.secondView();
    assertEquals(activity.view2, realDisplay.widget);

    activity.firstView();
    assertEquals(activity.view, realDisplay.widget);

    activity.secondView();
    assertEquals(activity.view2, realDisplay.widget);
  }
}
