/*
 * Copyright 2011 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.web.bindery.autobean.shared.impl;

import com.google.web.bindery.autobean.shared.Splittable;
import com.google.web.bindery.autobean.shared.impl.AutoBeanCodexImpl.Coder;
import com.google.web.bindery.autobean.shared.impl.AutoBeanCodexImpl.EncodeState;

import java.util.AbstractList;

/**
 * A list implementation that lazily reifies its constituent elements.
 * 
 * @param <E> the element type
 */
public class SplittableList<E> extends AbstractList<E> implements HasSplittable {
  static <Q> Q reify(EncodeState state, Splittable data, int index, Coder coder) {
    if (data.isNull(index)) {
      return null;
    }
    @SuppressWarnings("unchecked")
    Q toReturn = (Q) coder.decode(state, data.get(index));
    data.setReified(String.valueOf(index), toReturn);
    return toReturn;
  }

  static void set(EncodeState state, Splittable data, int index, Coder coder, Object value) {
    data.setReified(String.valueOf(index), value);
    if (value == null) {
      Splittable.NULL.assign(data, index);
      return;
    }
    Splittable backing = coder.extractSplittable(state, value);
    if (backing == null) {
      /*
       * External data type, such as an ArrayList or a concrete implementation
       * of a setter's interface type. This means that a slow serialization pass
       * is necessary.
       */
      data.setReified(AbstractAutoBean.UNSPLITTABLE_VALUES_KEY, true);
    } else {
      backing.assign(data, index);
    }
  }

  private Splittable data;
  private final Coder elementCoder;
  private final EncodeState state;

  public SplittableList(Splittable data, Coder elementCoder, EncodeState state) {
    assert data.isIndexed() : "Expecting indexed data";
    this.data = data;
    this.elementCoder = elementCoder;
    this.state = state;
  }

  @Override
  public void add(int index, E element) {
    set(state, data, index, elementCoder, element);
  }

  @Override
  public E get(int index) {
    if (data.isReified(String.valueOf(index))) {
      @SuppressWarnings("unchecked")
      E toReturn = (E) data.getReified(String.valueOf(index));
      return toReturn;
    }
    // javac generics bug
    return SplittableList.<E> reify(state, data, index, elementCoder);
  }

  public Splittable getSplittable() {
    return data;
  }

  @Override
  public E remove(int index) {
    E toReturn = get(index);
    // XXX This is terrible, use Array.splice
    int newSize = data.size() - 1;
    for (int i = index; i < newSize; i++) {
      data.get(i + 1).assign(data, i);
      // reified value for index 'i'  may needs to be updated
      if (data.isReified(String.valueOf(i + 1))) {
        data.setReified(String.valueOf(i), data.getReified(String.valueOf(i + 1)));
      } else if (data.isReified(String.valueOf(i))) {
        // Remove outdated value. Will be regenerated if needed.
        data.removeReified(String.valueOf(i));
      }
    }
    // clean-up last entry as one element has been removed
    data.removeReified(String.valueOf(newSize));
    data.setSize(newSize);
    return toReturn;
  }

  @Override
  public E set(int index, E element) {
    E previous = get(index);
    set(state, data, index, elementCoder, element);
    return previous;
  }

  @Override
  public int size() {
    return data.size();
  }
}
