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

import com.google.web.bindery.autobean.shared.AutoBean;
import com.google.web.bindery.autobean.shared.AutoBeanFactory;
import com.google.web.bindery.autobean.shared.AutoBeanUtils;
import com.google.web.bindery.autobean.shared.AutoBeanVisitor;
import com.google.web.bindery.autobean.shared.AutoBeanVisitor.Context;
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 com.google.gwt.core.client.impl.WeakMapping;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Basic implementation.
 * 
 * @param <T> the wrapper type
 */
public abstract class AbstractAutoBean<T> implements AutoBean<T>, HasSplittable {
  /**
   * Used to avoid cycles when visiting.
   */
  public static class OneShotContext implements Context {
    private final Set<AbstractAutoBean<?>> seen = new HashSet<AbstractAutoBean<?>>();

    public boolean hasSeen(AbstractAutoBean<?> bean) {
      return !seen.add(bean);
    }
  }

  public static final String UNSPLITTABLE_VALUES_KEY = "__unsplittableValues";
  protected static final Object[] EMPTY_OBJECT = new Object[0];

  /**
   * Used by {@link #createSimplePeer()}.
   */
  protected Splittable data;
  protected T wrapped;
  private final AutoBeanFactory factory;
  private boolean frozen;
  /**
   * Lazily initialized by {@link #setTag(String, Object)} because not all
   * instances will make use of tags.
   */
  private Map<String, Object> tags;
  private final boolean usingSimplePeer;

  /**
   * Constructor that will use a generated simple peer.
   */
  protected AbstractAutoBean(AutoBeanFactory factory) {
    this(factory, StringQuoter.createSplittable());
  }

  /**
   * Constructor that will use a generated simple peer, backed with existing
   * data.
   */
  protected AbstractAutoBean(AutoBeanFactory factory, Splittable data) {
    this.data = data;
    this.factory = factory;
    usingSimplePeer = true;
    wrapped = createSimplePeer();
  }

  /**
   * Constructor that wraps an existing object. The parameters on this method
   * are reversed to avoid conflicting with the other two-arg constructor for
   * {@code AutoBean<Splittable>} instances.
   */
  protected AbstractAutoBean(T wrapped, AutoBeanFactory factory) {
    this.factory = factory;
    usingSimplePeer = false;
    data = null;
    this.wrapped = wrapped;

    // Used by AutoBeanUtils
    WeakMapping.set(wrapped, AutoBean.class.getName(), this);
  }

  public void accept(AutoBeanVisitor visitor) {
    traverse(visitor, new OneShotContext());
  }

  public abstract T as();

  public AutoBean<T> clone(boolean deep) {
    throw new UnsupportedOperationException();
  }

  public AutoBeanFactory getFactory() {
    return factory;
  }

  public Splittable getSplittable() {
    return data;
  }

  @SuppressWarnings("unchecked")
  public <Q> Q getTag(String tagName) {
    return tags == null ? null : (Q) tags.get(tagName);
  }

  /**
   * Indicates that the value returned from {@link #getSplittable()} may not
   * contain all of the data encapsulated by the AutoBean.
   */
  public boolean hasUnsplittableValues() {
    return data.isReified(UNSPLITTABLE_VALUES_KEY);
  }

  public boolean isFrozen() {
    return frozen;
  }

  public boolean isWrapper() {
    return !usingSimplePeer;
  }

  public void setData(Splittable data) {
    assert data != null : "null data";
    this.data = data;
    /*
     * The simple peer aliases the data object from the enclosing bean to avoid
     * needing to call up the this.this$0 chain.
     */
    wrapped = createSimplePeer();
  }

  public void setFrozen(boolean frozen) {
    this.frozen = frozen;
  }

  public void setTag(String tagName, Object value) {
    if (tags == null) {
      tags = new HashMap<String, Object>();
    }
    tags.put(tagName, value);
  }

  public void traverse(AutoBeanVisitor visitor, OneShotContext ctx) {
    // Avoid cycles
    if (ctx.hasSeen(this)) {
      return;
    }
    if (visitor.visit(this, ctx)) {
      traverseProperties(visitor, ctx);
    }
    visitor.endVisit(this, ctx);
  }

  public T unwrap() {
    if (usingSimplePeer) {
      throw new IllegalStateException();
    }
    try {
      WeakMapping.set(wrapped, AutoBean.class.getName(), null);
      return wrapped;
    } finally {
      wrapped = null;
    }
  }

  /**
   * No-op. Used as a debugger hook point for generated code.
   * 
   * @param method the method name
   * @param returned the returned object
   * @param parameters the parameter list
   */
  protected void call(String method, Object returned, Object... parameters) {
  }

  protected void checkFrozen() {
    if (frozen) {
      throw new IllegalStateException("The AutoBean has been frozen");
    }
  }

  protected void checkWrapped() {
    if (wrapped == null && !usingSimplePeer) {
      throw new IllegalStateException("The AutoBean has been unwrapped");
    }
  }

  protected T createSimplePeer() {
    throw new UnsupportedOperationException();
  }

  /**
   * No-op. Used as a debugger hook point for generated code.
   * 
   * @param method the method name
   * @param toReturn the value to return
   */
  protected <V> V get(String method, V toReturn) {
    return toReturn;
  }

  protected <W> W getFromWrapper(W obj) {
    // Some versions of javac have problem inferring the generics here
    return AutoBeanUtils.<W, W> getAutoBean(obj).as();
  }

  /**
   * Native getters and setters for primitive properties are generated for each
   * type to ensure inlining.
   */
  protected <Q> Q getOrReify(String propertyName) {
    checkWrapped();
    if (data.isReified(propertyName)) {
      @SuppressWarnings("unchecked")
      Q temp = (Q) data.getReified(propertyName);
      return temp;
    }
    if (data.isNull(propertyName)) {
      return null;
    }
    data.setReified(propertyName, null);
    Coder coder = AutoBeanCodexImpl.doCoderFor(this, propertyName);
    @SuppressWarnings("unchecked")
    Q toReturn = (Q) coder.decode(EncodeState.forDecode(factory), data.get(propertyName));
    data.setReified(propertyName, toReturn);
    return toReturn;
  }

  protected T getWrapped() {
    checkWrapped();
    return wrapped;
  }

  protected boolean isUsingSimplePeer() {
    return usingSimplePeer;
  }

  protected boolean isWrapped(Object obj) {
    return AutoBeanUtils.getAutoBean(obj) != null;
  }

  /**
   * No-op. Used as a debugger hook point for generated code.
   * 
   * @param method the method name
   * @param value the Object value to be set
   */
  protected void set(String method, Object value) {
  }

  protected void setProperty(String propertyName, Object value) {
    checkWrapped();
    checkFrozen();
    data.setReified(propertyName, value);
    if (value == null) {
      Splittable.NULL.assign(data, propertyName);
      return;
    }
    Coder coder = AutoBeanCodexImpl.doCoderFor(this, propertyName);
    Splittable backing = coder.extractSplittable(EncodeState.forDecode(factory), 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(UNSPLITTABLE_VALUES_KEY, true);
    } else {
      backing.assign(data, propertyName);
    }
  }

  protected abstract void traverseProperties(AutoBeanVisitor visitor, OneShotContext ctx);
}
