// CHECKSTYLE_OFF: Copyrighted to ASF
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to You 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.
 *
 * THIS CODE HAS BEEN EXTENSIVELY HACKED BY GOOGLE TO WORK WITH GWT.
 */
// CHECKSTYLE_ON
package com.google.gwt.emultest.java.util;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.NoSuchElementException;

/**
 * Abstract class for testing the ListIterator interface.
 *
 * <p>This class provides a framework for testing an implementation of ListIterator. Concrete
 * subclasses must provide the list iterator to be tested. They must also specify certain details of
 * how the list iterator operates by overriding the supportsXxx() methods if necessary.
 */
@SuppressWarnings({"unchecked", "rawtypes"})
abstract class AbstractTestListIterator extends TestIterator {

  // -----------------------------------------------------------------------
  /**
   * Implement this method to return a list iterator over an empty collection.
   *
   * @return an empty iterator
   */
  public abstract ListIterator makeEmptyListIterator();

  /**
   * Implement this method to return a list iterator over a collection with elements.
   *
   * @return a full iterator
   */
  public abstract ListIterator makeFullListIterator();

  /**
   * Implements the abstract superclass method to return the list iterator.
   *
   * @return an empty iterator
   */
  @Override
  public Iterator makeEmptyIterator() {
    return makeEmptyListIterator();
  }

  /**
   * Implements the abstract superclass method to return the list iterator.
   *
   * @return a full iterator
   */
  @Override
  public Iterator makeFullIterator() {
    return makeFullListIterator();
  }

  /**
   * Whether or not we are testing an iterator that supports add(). Default is true.
   *
   * @return true if Iterator supports add
   */
  public boolean supportsAdd() {
    return true;
  }

  /**
   * Whether or not we are testing an iterator that supports set(). Default is true.
   *
   * @return true if Iterator supports set
   */
  public boolean supportsSet() {
    return true;
  }

  /** The value to be used in the add and set tests. Default is null. */
  public Object addSetValue() {
    return null;
  }

  // -----------------------------------------------------------------------
  /** Test that the empty list iterator contract is correct. */
  public void testEmptyListIteratorIsIndeedEmpty() {
    if (supportsEmptyIterator() == false) {
      return;
    }

    ListIterator it = makeEmptyListIterator();

    assertEquals(false, it.hasNext());
    assertEquals(0, it.nextIndex());
    assertEquals(false, it.hasPrevious());
    assertEquals(-1, it.previousIndex());

    // next() should throw a NoSuchElementException
    try {
      it.next();
      fail("NoSuchElementException must be thrown from empty ListIterator");
    } catch (NoSuchElementException e) {
    }

    // previous() should throw a NoSuchElementException
    try {
      it.previous();
      fail("NoSuchElementException must be thrown from empty ListIterator");
    } catch (NoSuchElementException e) {
    }
  }

  /** Test navigation through the iterator. */
  public void testWalkForwardAndBack() {
    ArrayList list = new ArrayList();
    ListIterator it = makeFullListIterator();
    while (it.hasNext()) {
      list.add(it.next());
    }

    // check state at end
    assertEquals(false, it.hasNext());
    assertEquals(true, it.hasPrevious());
    try {
      it.next();
      fail("NoSuchElementException must be thrown from next at end of ListIterator");
    } catch (NoSuchElementException e) {
    }

    // loop back through comparing
    for (int i = list.size() - 1; i >= 0; i--) {
      assertEquals(i + 1, it.nextIndex());
      assertEquals(i, it.previousIndex());

      Object obj = list.get(i);
      assertEquals(obj, it.previous());
    }

    // check state at start
    assertEquals(true, it.hasNext());
    assertEquals(false, it.hasPrevious());
    try {
      it.previous();
      fail("NoSuchElementException must be thrown from previous at start of ListIterator");
    } catch (NoSuchElementException e) {
    }
  }

  /** Test add behaviour. */
  public void testAdd() {
    ListIterator it = makeFullListIterator();

    Object addValue = addSetValue();
    if (supportsAdd() == false) {
      // check for UnsupportedOperationException if not supported
      try {
        it.add(addValue);
      } catch (UnsupportedOperationException ex) {
      }
      return;
    }

    // add at start should be OK, added should be previous
    it = makeFullListIterator();
    it.add(addValue);
    assertEquals(addValue, it.previous());

    // add at start should be OK, added should not be next
    it = makeFullListIterator();
    it.add(addValue);
    assertTrue(addValue != it.next());

    // add in middle and at end should be OK
    it = makeFullListIterator();
    while (it.hasNext()) {
      it.next();
      it.add(addValue);
      // check add OK
      assertEquals(addValue, it.previous());
      it.next();
    }
  }

  /** Test set behaviour. */
  public void testSet() {
    ListIterator it = makeFullListIterator();

    if (supportsSet() == false) {
      // check for UnsupportedOperationException if not supported
      try {
        it.set(addSetValue());
      } catch (UnsupportedOperationException ex) {
      }
      return;
    }

    // should throw IllegalStateException before next() called
    try {
      it.set(addSetValue());
      fail();
    } catch (IllegalStateException ex) {
    }

    // set after next should be fine
    it.next();
    it.set(addSetValue());

    // repeated set calls should be fine
    it.set(addSetValue());
  }

  public void testRemoveThenSet() {
    ListIterator it = makeFullListIterator();
    if (supportsRemove() && supportsSet()) {
      it.next();
      it.remove();
      try {
        it.set(addSetValue());
        fail("IllegalStateException must be thrown from set after remove");
      } catch (IllegalStateException e) {
      }
    }
  }

  public void testAddThenSet() {
    ListIterator it = makeFullListIterator();
    // add then set
    if (supportsAdd() && supportsSet()) {
      it.next();
      it.add(addSetValue());
      try {
        it.set(addSetValue());
        fail("IllegalStateException must be thrown from set after add");
      } catch (IllegalStateException e) {
      }
    }
  }

  /** Test remove after add behaviour. */
  public void testAddThenRemove() {
    ListIterator it = makeFullListIterator();

    // add then remove
    if (supportsAdd() && supportsRemove()) {
      it.next();
      it.add(addSetValue());
      try {
        it.remove();
        fail("IllegalStateException must be thrown from remove after add");
      } catch (IllegalStateException e) {
      }
    }
  }
}
