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

import com.google.gwt.autobean.shared.impl.EnumMap;
import com.google.gwt.autobean.shared.impl.LazySplittable;
import com.google.gwt.autobean.shared.impl.StringQuoter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

/**
 * Utility methods for encoding an AutoBean graph into a JSON-compatible string.
 * This codex intentionally does not preserve object identity, nor does it
 * encode cycles, but it will detect them.
 */
public class AutoBeanCodex {
  static class Decoder extends AutoBeanVisitor {
    private final Stack<AutoBean<?>> beanStack = new Stack<AutoBean<?>>();
    private final Stack<Splittable> dataStack = new Stack<Splittable>();
    private AutoBean<?> bean;
    private Splittable data;
    private final AutoBeanFactory factory;

    public Decoder(AutoBeanFactory factory) {
      this.factory = factory;
    }

    @SuppressWarnings("unchecked")
    public <T> AutoBean<T> decode(Splittable data, Class<T> type) {
      push(data, type);
      bean.accept(this);
      return (AutoBean<T>) pop();
    }

    @Override
    public boolean visitCollectionProperty(String propertyName,
        AutoBean<Collection<?>> value, CollectionPropertyContext ctx) {
      if (data.isNull(propertyName)) {
        return false;
      }

      Collection<Object> collection;
      if (List.class.equals(ctx.getType())) {
        collection = new ArrayList<Object>();
      } else if (Set.class.equals(ctx.getType())) {
        collection = new HashSet<Object>();
      } else {
        throw new UnsupportedOperationException("Only List and Set supported");
      }

      boolean isValue = ValueCodex.canDecode(ctx.getElementType());
      boolean isEncoded = Splittable.class.equals(ctx.getElementType());
      Splittable listData = data.get(propertyName);
      for (int i = 0, j = listData.size(); i < j; i++) {
        if (listData.isNull(i)) {
          collection.add(null);
        } else {
          if (isValue) {
            collection.add(decodeValue(ctx.getElementType(), listData.get(i)));
          } else if (isEncoded) {
            collection.add(listData.get(i));
          } else {
            collection.add(decode(listData.get(i), ctx.getElementType()).as());
          }
        }
      }
      ctx.set(collection);
      return false;
    }

    @Override
    public boolean visitMapProperty(String propertyName,
        AutoBean<Map<?, ?>> value, MapPropertyContext ctx) {
      if (data.isNull(propertyName)) {
        return false;
      }

      Map<?, ?> map;
      if (ValueCodex.canDecode(ctx.getKeyType())) {
        map = decodeValueKeyMap(data.get(propertyName), ctx.getKeyType(),
            ctx.getValueType());
      } else {
        map = decodeObjectKeyMap(data.get(propertyName), ctx.getKeyType(),
            ctx.getValueType());
      }
      ctx.set(map);
      return false;
    }

    @Override
    public boolean visitReferenceProperty(String propertyName,
        AutoBean<?> value, PropertyContext ctx) {
      if (data.isNull(propertyName)) {
        return false;
      }

      if (Splittable.class.equals(ctx.getType())) {
        ctx.set(data.get(propertyName));
        return false;
      }

      push(data.get(propertyName), ctx.getType());
      bean.accept(this);
      ctx.set(pop().as());
      return false;
    }

    @Override
    public boolean visitValueProperty(String propertyName, Object value,
        PropertyContext ctx) {
      if (!data.isNull(propertyName)) {
        Object object;
        Splittable propertyValue = data.get(propertyName);
        Class<?> type = ctx.getType();
        object = decodeValue(type, propertyValue);
        ctx.set(object);
      }
      return false;
    }

    private Map<?, ?> decodeObjectKeyMap(Splittable map, Class<?> keyType,
        Class<?> valueType) {
      boolean isEncodedKey = Splittable.class.equals(keyType);
      boolean isEncodedValue = Splittable.class.equals(valueType);
      boolean isValueValue = Splittable.class.equals(valueType);

      Splittable keyList = map.get(0);
      Splittable valueList = map.get(1);
      assert keyList.size() == valueList.size();

      Map<Object, Object> toReturn = new HashMap<Object, Object>(keyList.size());
      for (int i = 0, j = keyList.size(); i < j; i++) {
        Object key;
        if (isEncodedKey) {
          key = keyList.get(i);
        } else {
          key = decode(keyList.get(i), keyType).as();
        }

        Object value;
        if (valueList.isNull(i)) {
          value = null;
        } else if (isEncodedValue) {
          value = keyList.get(i);
        } else if (isValueValue) {
          value = decodeValue(valueType, keyList.get(i));
        } else {
          value = decode(valueList.get(i), valueType).as();
        }

        toReturn.put(key, value);
      }
      return toReturn;
    }

    private Object decodeValue(Class<?> type, Splittable propertyValue) {
      return decodeValue(type, propertyValue.asString());
    }

    private Object decodeValue(Class<?> type, String propertyValue) {
      Object object;
      if (type.isEnum() && bean.getFactory() instanceof EnumMap) {
        // The generics kind of get in the way here
        @SuppressWarnings({"unchecked", "rawtypes"})
        Class<Enum> enumType = (Class<Enum>) type;
        @SuppressWarnings("unchecked")
        Enum<?> e = ((EnumMap) bean.getFactory()).getEnum(enumType,
            propertyValue);
        object = e;
      } else {
        object = ValueCodex.decode(type, propertyValue);
      }
      return object;
    }

    private Map<?, ?> decodeValueKeyMap(Splittable map, Class<?> keyType,
        Class<?> valueType) {
      Map<Object, Object> toReturn = new HashMap<Object, Object>();

      boolean isEncodedValue = Splittable.class.equals(valueType);
      boolean isValueValue = ValueCodex.canDecode(valueType);
      for (String encodedKey : map.getPropertyKeys()) {
        Object key = decodeValue(keyType, encodedKey);
        Object value;
        if (map.isNull(encodedKey)) {
          value = null;
        } else if (isEncodedValue) {
          value = map.get(encodedKey);
        } else if (isValueValue) {
          value = decodeValue(valueType, map.get(encodedKey));
        } else {
          value = decode(map.get(encodedKey), valueType).as();
        }
        toReturn.put(key, value);
      }

      return toReturn;
    }

    private AutoBean<?> pop() {
      dataStack.pop();
      if (dataStack.isEmpty()) {
        data = null;
      } else {
        data = dataStack.peek();
      }
      AutoBean<?> toReturn = beanStack.pop();
      if (beanStack.isEmpty()) {
        bean = null;
      } else {
        bean = beanStack.peek();
      }
      return toReturn;
    }

    private void push(Splittable data, Class<?> type) {
      this.data = data;
      bean = factory.create(type);
      if (bean == null) {
        throw new IllegalArgumentException(
            "The AutoBeanFactory cannot create a " + type.getName());
      }
      dataStack.push(data);
      beanStack.push(bean);
    }
  }

  static class Encoder extends AutoBeanVisitor {
    private EnumMap enumMap;
    private Set<AutoBean<?>> seen = new HashSet<AutoBean<?>>();
    private Stack<StringBuilder> stack = new Stack<StringBuilder>();
    private StringBuilder sb;

    public Encoder(AutoBeanFactory factory) {
      if (factory instanceof EnumMap) {
        enumMap = (EnumMap) factory;
      }
    }

    @Override
    public void endVisit(AutoBean<?> bean, Context ctx) {
      if (sb.length() == 0) {
        // No properties
        sb.append("{");
      } else {
        sb.setCharAt(0, '{');
      }
      sb.append("}");
    }

    @Override
    public void endVisitReferenceProperty(String propertyName,
        AutoBean<?> value, PropertyContext ctx) {
      StringBuilder popped = pop();
      if (popped.length() > 0) {
        sb.append(",\"").append(propertyName).append("\":").append(
            popped.toString());
      }
    }

    @Override
    public boolean visitCollectionProperty(String propertyName,
        AutoBean<Collection<?>> value, CollectionPropertyContext ctx) {
      push(new StringBuilder());

      if (value == null) {
        return false;
      }

      Collection<?> collection = value.as();
      if (collection.isEmpty()) {
        sb.append("[]");
        return false;
      }

      if (ValueCodex.canDecode(ctx.getElementType())) {
        for (Object element : collection) {
          sb.append(",").append(encodeValue(element).getPayload());
        }
      } else {
        boolean isEncoded = Splittable.class.equals(ctx.getElementType());
        for (Object element : collection) {
          sb.append(",");
          if (element == null) {
            sb.append("null");
          } else if (isEncoded) {
            sb.append(((Splittable) element).getPayload());
          } else {
            encodeToStringBuilder(sb, element);
          }
        }
      }
      sb.setCharAt(0, '[');
      sb.append("]");
      return false;
    }

    @Override
    public boolean visitMapProperty(String propertyName,
        AutoBean<Map<?, ?>> value, MapPropertyContext ctx) {
      push(new StringBuilder());

      if (value == null) {
        return false;
      }

      Map<?, ?> map = value.as();
      if (map.isEmpty()) {
        sb.append("{}");
        return false;
      }

      boolean isEncodedKey = Splittable.class.equals(ctx.getKeyType());
      boolean isEncodedValue = Splittable.class.equals(ctx.getValueType());
      boolean isValueKey = ValueCodex.canDecode(ctx.getKeyType());
      boolean isValueValue = ValueCodex.canDecode(ctx.getValueType());

      if (isValueKey) {
        writeValueKeyMap(map, isEncodedValue, isValueValue);
      } else {
        writeObjectKeyMap(map, isEncodedKey, isEncodedValue, isValueValue);
      }

      return false;
    }

    @Override
    public boolean visitReferenceProperty(String propertyName,
        AutoBean<?> value, PropertyContext ctx) {
      push(new StringBuilder());

      if (value == null) {
        return false;
      }

      if (Splittable.class.equals(ctx.getType())) {
        sb.append(((Splittable) value.as()).getPayload());
        return false;
      }

      if (seen.contains(value)) {
        haltOnCycle();
      }

      return true;
    }

    @Override
    public boolean visitValueProperty(String propertyName, Object value,
        PropertyContext ctx) {
      // Skip primitive types whose values are uninteresting.
      Class<?> type = ctx.getType();
      Object blankValue = ValueCodex.getUninitializedFieldValue(type);
      if (value == blankValue || value != null && value.equals(blankValue)) {
        return false;
      }

      // Special handling for enums if we have an obfuscation map
      Splittable split;
      split = encodeValue(value);
      sb.append(",\"").append(propertyName).append("\":").append(
          split.getPayload());
      return false;
    }

    StringBuilder pop() {
      StringBuilder toReturn = stack.pop();
      sb = stack.peek();
      return toReturn;
    }

    void push(StringBuilder sb) {
      stack.push(sb);
      this.sb = sb;
    }

    private void encodeToStringBuilder(StringBuilder accumulator, Object value) {
      push(new StringBuilder());
      AutoBean<?> bean = AutoBeanUtils.getAutoBean(value);
      if (!seen.add(bean)) {
        haltOnCycle();
      }
      bean.accept(this);
      accumulator.append(pop().toString());
      seen.remove(bean);
    }

    /**
     * Encodes a value, with special handling for enums to allow the field name
     * to be overridden.
     */
    private Splittable encodeValue(Object value) {
      Splittable split;
      if (value instanceof Enum<?> && enumMap != null) {
        split = ValueCodex.encode(enumMap.getToken((Enum<?>) value));
      } else {
        split = ValueCodex.encode(value);
      }
      return split;
    }

    private void haltOnCycle() {
      throw new HaltException(new UnsupportedOperationException(
          "Cycle detected"));
    }

    /**
     * Writes a map JSON literal where the keys are object types. This is
     * encoded as a list of two lists, since it's possible that two distinct
     * objects have the same encoded form.
     */
    private void writeObjectKeyMap(Map<?, ?> map, boolean isEncodedKey,
        boolean isEncodedValue, boolean isValueValue) {
      StringBuilder keys = new StringBuilder();
      StringBuilder values = new StringBuilder();

      for (Map.Entry<?, ?> entry : map.entrySet()) {
        if (isEncodedKey) {
          keys.append(",").append(((Splittable) entry.getKey()).getPayload());
        } else {
          encodeToStringBuilder(keys.append(","), entry.getKey());
        }

        if (isEncodedValue) {
          values.append(",").append(
              ((Splittable) entry.getValue()).getPayload());
        } else if (isValueValue) {
          values.append(",").append(encodeValue(entry.getValue()).getPayload());
        } else {
          encodeToStringBuilder(values.append(","), entry.getValue());
        }
      }
      keys.setCharAt(0, '[');
      keys.append("]");
      values.setCharAt(0, '[');
      values.append("]");

      sb.append("[").append(keys.toString()).append(",").append(
          values.toString()).append("]");
    }

    /**
     * Writes a map JSON literal where the keys are value types.
     */
    private void writeValueKeyMap(Map<?, ?> map, boolean isEncodedValue,
        boolean isValueValue) {
      for (Map.Entry<?, ?> entry : map.entrySet()) {
        sb.append(",").append(encodeValue(entry.getKey()).getPayload()).append(
            ":");
        if (isEncodedValue) {
          sb.append(((Splittable) entry.getValue()).getPayload());
        } else if (isValueValue) {
          sb.append(encodeValue(entry.getValue()).getPayload());
        } else {
          encodeToStringBuilder(sb, entry.getValue());
        }
      }
      sb.setCharAt(0, '{');
      sb.append("}");
    }
  }

  /**
   * Used to stop processing.
   */
  static class HaltException extends RuntimeException {
    public HaltException(RuntimeException cause) {
      super(cause);
    }

    @Override
    public RuntimeException getCause() {
      return (RuntimeException) super.getCause();
    }
  }

  public static <T> AutoBean<T> decode(AutoBeanFactory factory, Class<T> clazz,
      Splittable data) {
    return new Decoder(factory).decode(data, clazz);
  }

  /**
   * Decode an AutoBeanCodex payload.
   * 
   * @param <T> the expected return type
   * @param factory an AutoBeanFactory capable of producing {@code AutoBean<T>}
   * @param clazz the expected return type
   * @param payload a payload string previously generated by
   *          {@link #encode(AutoBean)}
   * @return an AutoBean containing the payload contents
   */
  public static <T> AutoBean<T> decode(AutoBeanFactory factory, Class<T> clazz,
      String payload) {
    Splittable data = StringQuoter.split(payload);
    return decode(factory, clazz, data);
  }

  /**
   * Encodes an AutoBean. The actual payload contents can be retrieved through
   * {@link Splittable#getPayload()}.
   * 
   * @param bean the bean to encode
   * @return a Splittable that encodes the state of the AutoBean
   */
  public static Splittable encode(AutoBean<?> bean) {
    if (bean == null) {
      return LazySplittable.NULL;
    }

    StringBuilder sb = new StringBuilder();
    encodeForJsoPayload(sb, bean);
    return new LazySplittable(sb.toString());
  }

  // ["prop",value,"prop",value, ...]
  private static void encodeForJsoPayload(StringBuilder sb, AutoBean<?> bean) {
    Encoder e = new Encoder(bean.getFactory());
    e.push(sb);
    try {
      bean.accept(e);
    } catch (HaltException ex) {
      throw ex.getCause();
    }
  }

  private AutoBeanCodex() {
  }
}
