/*
 * 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.place.impl;

import com.google.gwt.core.client.GWT;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceHistoryMapper;
import com.google.gwt.place.shared.PlaceHistoryMapperWithFactory;
import com.google.gwt.place.shared.WithTokenizers;
import com.google.gwt.place.testplacemappers.NoFactory;
import com.google.gwt.place.testplacemappers.WithFactory;
import com.google.gwt.place.testplaces.Place1;
import com.google.gwt.place.testplaces.Place2;
import com.google.gwt.place.testplaces.Place3;
import com.google.gwt.place.testplaces.Place4;
import com.google.gwt.place.testplaces.Place5;
import com.google.gwt.place.testplaces.Tokenizer2;
import com.google.gwt.place.testplaces.Tokenizer3;
import com.google.gwt.place.testplaces.Tokenizer4;
import com.google.gwt.place.testplaces.TokenizerFactory;

/**
 * Functional test of PlaceHistoryMapperGenerator.
 */
public class PlaceHistoryMapperGeneratorTest extends GWTTestCase {
  @WithTokenizers({
      Place1.Tokenizer.class, Tokenizer2.class, Tokenizer3.class,
      Tokenizer4.class})
  interface LocalNoFactory extends PlaceHistoryMapper {
  };

  @WithTokenizers(Tokenizer4.class)
  interface LocalWithFactory extends
      PlaceHistoryMapperWithFactory<TokenizerFactory> {
  };

  @Override
  public String getModuleName() {
    return "com.google.gwt.place.PlaceSuite";
  }

  Place1 place1 = new Place1("able");
  Place2 place2 = new Place2("baker");
  Place3 place3 = new Place3("charlie");
  Place4 place4 = new Place4("delta");
  Place5 place5 = new Place5("echo");

  public void testTopLevelWithoutFactory() {
    AbstractPlaceHistoryMapper<?> subject = GWT.create(NoFactory.class);

    doTest(subject, null);
  }

  public void testTopLevelWithFactory() {
    AbstractPlaceHistoryMapper<TokenizerFactory> subject = GWT.create(WithFactory.class);
    TokenizerFactory factory = new TokenizerFactory();
    subject.setFactory(factory);

    doTest(subject, factory);
  }

  public void testNestedWithoutFactory() {
    AbstractPlaceHistoryMapper<?> subject = GWT.create(LocalNoFactory.class);

    doTest(subject, null);
  }

  public void testNestedWithFactory() {
    AbstractPlaceHistoryMapper<TokenizerFactory> subject = GWT.create(LocalWithFactory.class);
    TokenizerFactory factory = new TokenizerFactory();
    subject.setFactory(factory);

    doTest(subject, factory);
  }

  // CHECKSTYLE_OFF
  private void doTest(AbstractPlaceHistoryMapper<?> subject,
      TokenizerFactory factory) {
    String history1 = subject.getPrefixAndToken(place1).toString();
    assertEquals(Place1.Tokenizer.PREFIX + ":" + place1.content, history1);

    String history2 = subject.getPrefixAndToken(place2).toString();
    if (factory != null) {
      assertEquals(TokenizerFactory.PLACE2_PREFIX + ":" + place2.content,
          history2);
    } else {
      assertEquals("Place2:" + place2.content, history2);
    }

    String history3 = subject.getPrefixAndToken(place3).toString();
    assertEquals("Place3:" + place3.content, history3);

    String history4 = subject.getPrefixAndToken(place4).toString();
    assertEquals("Place4:" + place4.content, history4);

    // Place 5 extends Place3 and does not have its own PlaceTokenizer
    String history5 = subject.getPrefixAndToken(place5).toString();
    assertEquals("Place3:" + place5.content, history5);

    if (factory != null) {
      assertEquals(factory.tokenizer,
          subject.getTokenizer(Place1.Tokenizer.PREFIX));
      assertEquals(factory.tokenizer2,
          subject.getTokenizer(TokenizerFactory.PLACE2_PREFIX));
      assertEquals(factory.tokenizer3, subject.getTokenizer("Place3"));
    } else {
      assertTrue(subject.getTokenizer(Place1.Tokenizer.PREFIX) instanceof Place1.Tokenizer);
      assertTrue(subject.getTokenizer("Place2") instanceof Tokenizer2);
      assertTrue(subject.getTokenizer("Place3") instanceof Tokenizer3);
    }
    assertTrue(subject.getTokenizer("Place4") instanceof Tokenizer4);

    Place place = new Place() {
    };
    assertNull(subject.getPrefixAndToken(place));
    assertNull(subject.getTokenizer("snot"));
  }
  // CHECKSTYLE_ON
}
