/*
 * Copyright 2009 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.rpc.server;

import com.google.gwt.rpc.client.ast.BooleanValueCommand;
import com.google.gwt.rpc.client.ast.ByteValueCommand;
import com.google.gwt.rpc.client.ast.CharValueCommand;
import com.google.gwt.rpc.client.ast.DoubleValueCommand;
import com.google.gwt.rpc.client.ast.FloatValueCommand;
import com.google.gwt.rpc.client.ast.IntValueCommand;
import com.google.gwt.rpc.client.ast.LongValueCommand;
import com.google.gwt.rpc.client.ast.ShortValueCommand;
import com.google.gwt.rpc.client.ast.StringValueCommand;
import com.google.gwt.rpc.client.ast.ValueCommand;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.client.rpc.SerializationStreamReader;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.IdentityHashMap;
import java.util.Map;

import sun.misc.Unsafe;

/**
 * Contains common utility code.
 */
public class CommandSerializationUtil {

  /**
   * Defines methods for getting and setting fields.
   */
  public interface Accessor {
    boolean canMakeValueCommand();

    /**
     * Indicates if set can be called with a value of the given type.
     */
    boolean canSet(Class<?> clazz);

    Object get(Object instance, Field f);

    Class<?> getTargetType();

    ValueCommand makeValueCommand(Object value);

    Object readNext(SerializationStreamReader reader)
        throws SerializationException;

    void set(Object instance, Field f, Object value);

    void set(Object array, int index, Object value);
  }

  /**
   * Defines type-specific methods of getting and setting fields.
   */
  private static enum TypeAccessor implements Accessor {
    BOOL {
      @Override
      public boolean canSet(Class<?> clazz) {
        return Boolean.class.isAssignableFrom(clazz);
      }

      @Override
      public Object get(Object instance, long offset) {
        return theUnsafe.getBoolean(instance, offset);
      }

      @Override
      public Object getDefaultValue() {
        return false;
      }

      @Override
      public Class<?> getTargetType() {
        return boolean.class;
      }

      @Override
      public ValueCommand makeValueCommand(Object value) {
        return new BooleanValueCommand((Boolean) value);
      }

      @Override
      public Object readNext(SerializationStreamReader reader)
          throws SerializationException {
        return reader.readBoolean();
      }

      @Override
      public void set(Object instance, long offset, Object value) {
        theUnsafe.putBoolean(instance, offset, toBoolean(value));
      }

      private boolean toBoolean(Object value) {
        if (value instanceof Number) {
          return ((Number) value).intValue() != 0;
        } else if (value instanceof String) {
          return Boolean.valueOf((String) value);
        } else {
          // returns false if the value is null.
          return Boolean.TRUE.equals(value);
        }
      }

    },
    BYTE {
      @Override
      public Object get(Object instance, long offset) {
        return theUnsafe.getByte(instance, offset);
      }

      @Override
      public Class<?> getTargetType() {
        return byte.class;
      }

      @Override
      public ValueCommand makeValueCommand(Object value) {
        return new ByteValueCommand((Byte) value);
      }

      @Override
      public Object readNext(SerializationStreamReader reader)
          throws SerializationException {
        return reader.readByte();
      }

      @Override
      public void set(Object instance, long offset, Object value) {
        theUnsafe.putByte(instance, offset, ((Number) value).byteValue());
      }
    },
    CHAR {
      @Override
      public Object get(Object instance, long offset) {
        return theUnsafe.getChar(instance, offset);
      }

      @Override
      public Class<?> getTargetType() {
        return char.class;
      }

      @Override
      public ValueCommand makeValueCommand(Object value) {
        return new CharValueCommand((Character) value);
      }

      @Override
      public Object readNext(SerializationStreamReader reader)
          throws SerializationException {
        return reader.readChar();
      }

      @Override
      public void set(Object instance, long offset, Object value) {
        char c = (value instanceof Number) ? (char) ((Number) value).intValue()
            : (Character) value;
        theUnsafe.putChar(instance, offset, c);
      }
    },
    DOUBLE {
      @Override
      public Object get(Object instance, long offset) {
        return theUnsafe.getDouble(instance, offset);
      }

      @Override
      public Class<?> getTargetType() {
        return double.class;
      }

      @Override
      public ValueCommand makeValueCommand(Object value) {
        return new DoubleValueCommand((Double) value);
      }

      @Override
      public Object readNext(SerializationStreamReader reader)
          throws SerializationException {
        return reader.readDouble();
      }

      @Override
      public void set(Object instance, long offset, Object value) {
        theUnsafe.putDouble(instance, offset, ((Number) value).doubleValue());
      }
    },
    FLOAT {
      @Override
      public Object get(Object instance, long offset) {
        return theUnsafe.getFloat(instance, offset);
      }

      @Override
      public Class<?> getTargetType() {
        return float.class;
      }

      @Override
      public ValueCommand makeValueCommand(Object value) {
        return new FloatValueCommand((Float) value);
      }

      @Override
      public Object readNext(SerializationStreamReader reader)
          throws SerializationException {
        return reader.readFloat();
      }

      @Override
      public void set(Object instance, long offset, Object value) {
        theUnsafe.putFloat(instance, offset, ((Number) value).floatValue());
      }
    },
    INT {
      @Override
      public Object get(Object instance, long offset) {
        return theUnsafe.getInt(instance, offset);
      }

      @Override
      public Class<?> getTargetType() {
        return int.class;
      }

      @Override
      public ValueCommand makeValueCommand(Object value) {
        return new IntValueCommand(((Number) value).intValue());
      }

      @Override
      public Object readNext(SerializationStreamReader reader)
          throws SerializationException {
        return reader.readInt();
      }

      @Override
      public void set(Object instance, long offset, Object value) {
        theUnsafe.putInt(instance, offset, ((Number) value).intValue());
      }
    },
    LONG {
      @Override
      public Object get(Object instance, long offset) {
        return theUnsafe.getLong(instance, offset);
      }

      @Override
      public Class<?> getTargetType() {
        return long.class;
      }

      @Override
      public ValueCommand makeValueCommand(Object value) {
        return new LongValueCommand((Long) value);
      }

      @Override
      public Object readNext(SerializationStreamReader reader)
          throws SerializationException {
        return reader.readLong();
      }

      @Override
      public void set(Object instance, long offset, Object value) {
        theUnsafe.putLong(instance, offset, ((Number) value).longValue());
      }
    },
    OBJECT {
      @Override
      public boolean canMakeValueCommand() {
        return false;
      }

      @Override
      public boolean canSet(Class<?> clazz) {
        return Object.class.isAssignableFrom(clazz);
      }

      @Override
      public Object get(Object instance, long offset) {
        return theUnsafe.getObject(instance, offset);
      }

      @Override
      public Object getDefaultValue() {
        return null;
      }

      @Override
      public Class<?> getTargetType() {
        return Object.class;
      }

      @Override
      public ValueCommand makeValueCommand(Object value) {
        throw new RuntimeException("Cannot call makeValueCommand for Objects");
      }

      @Override
      public Object readNext(SerializationStreamReader reader)
          throws SerializationException {
        return reader.readObject();
      }

      @Override
      public void set(Object instance, long offset, Object value) {
        theUnsafe.putObject(instance, offset, value);
      }
    },
    SHORT {
      @Override
      public Object get(Object instance, long offset) {
        return theUnsafe.getShort(instance, offset);
      }

      @Override
      public Class<?> getTargetType() {
        return short.class;
      }

      @Override
      public ValueCommand makeValueCommand(Object value) {
        return new ShortValueCommand((Short) value);
      }

      @Override
      public Object readNext(SerializationStreamReader reader)
          throws SerializationException {
        return reader.readShort();
      }

      @Override
      public void set(Object instance, long offset, Object value) {
        theUnsafe.putShort(instance, offset, ((Number) value).shortValue());
      }
    },
    STRING {
      @Override
      public boolean canSet(Class<?> clazz) {
        return true;
      }

      @Override
      public Object get(Object instance, long offset) {
        return theUnsafe.getObject(instance, offset);
      }

      @Override
      public Object getDefaultValue() {
        return null;
      }

      @Override
      public Class<?> getTargetType() {
        return String.class;
      }

      @Override
      public ValueCommand makeValueCommand(Object value) {
        return new StringValueCommand((String) value);
      }

      @Override
      public Object readNext(SerializationStreamReader reader)
          throws SerializationException {
        return reader.readObject();
      }

      @Override
      public void set(Object instance, long offset, Object value) {
        theUnsafe.putObject(instance, offset, value == null ? null
            : value.toString());
      }
    };

    private final Class<?> arrayType = Array.newInstance(getTargetType(), 0).getClass();
    private final long arrayBase = theUnsafe.arrayBaseOffset(arrayType);
    private final long arrayIndexScale = theUnsafe.arrayIndexScale(arrayType);

    public boolean canMakeValueCommand() {
      return true;
    }

    public boolean canSet(Class<?> clazz) {
      return Number.class.isAssignableFrom(clazz);
    }

    public Object get(Object instance, Field f) {
      long offset = objectFieldOffset(f);
      return get(instance, offset);
    }

    public abstract Object get(Object instance, long offset);

    public Object getDefaultValue() {
      return 0;
    }

    public abstract Class<?> getTargetType();

    public abstract ValueCommand makeValueCommand(Object value);

    public abstract Object readNext(SerializationStreamReader reader)
        throws SerializationException;

    public void set(Object instance, Field f, Object value) {
      long offset = objectFieldOffset(f);
      set(instance, offset, value == null ? getDefaultValue() : value);
    }

    public void set(Object array, int index, Object value) {
      set(array, arrayBase + arrayIndexScale * index, value);
    }

    public abstract void set(Object instance, long offset, Object value);
  }

  private static final Map<Class<?>, Accessor> ACCESSORS = new IdentityHashMap<Class<?>, Accessor>();
  private static final Unsafe theUnsafe;

  static {
    Exception ex = null;
    Unsafe localUnsafe = null;
    try {
      Field f = Unsafe.class.getDeclaredField("theUnsafe");
      f.setAccessible(true);
      localUnsafe = (Unsafe) f.get(null);
    } catch (SecurityException e) {
      ex = e;
    } catch (NoSuchFieldException e) {
      ex = e;
    } catch (IllegalArgumentException e) {
      ex = e;
    } catch (IllegalAccessException e) {
      ex = e;
    }
    if (ex != null) {
      throw new RuntimeException("Unable to get Unsafe instance", ex);
    } else {
      theUnsafe = localUnsafe;
    }

    for (TypeAccessor setter : TypeAccessor.values()) {
      ACCESSORS.put(setter.getTargetType(), setter);
    }
  }

  public static Accessor getAccessor(Class<?> clazz) {
    Accessor toReturn = ACCESSORS.get(clazz);
    if (toReturn == null) {
      toReturn = TypeAccessor.OBJECT;
    }
    return toReturn;
  }

  /**
   * TODO: In the future it may be preferable to use a custom ClassLoader to
   * inject a constructor that will initialize all of the final fields that we
   * care about.
   */
  static <T> T allocateInstance(Class<T> clazz) throws InstantiationException {
    Object obj = theUnsafe.allocateInstance(clazz);
    return clazz.cast(obj);
  }

  private static long objectFieldOffset(Field f) {
    return theUnsafe.objectFieldOffset(f);
  }

  private CommandSerializationUtil() {
  }
}
