/*
 * 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.
 */
package org.apache.geode.pdx;

import java.nio.ByteBuffer;
import java.util.Date;

import org.apache.geode.internal.serialization.DSCODE;
import org.apache.geode.internal.serialization.StaticSerialization;
import org.apache.geode.pdx.internal.DataSize;

/**
 * Every field of a pdx must have one of these types. The type of that field can never change. If
 * you do want to be able to change a field's class then its field type needs to be {@link #OBJECT}.
 * Some field types are always serialized with a certain number of bytes; these are called
 * "fixed-width". Others are serialized with a variable number of bytes; these are called
 * "variable-width".
 *
 * @since GemFire 6.6.2
 */
public enum FieldType {
  BOOLEAN(true, DataSize.BOOLEAN_SIZE, "boolean", new byte[] {0}, false),
  BYTE(true, DataSize.BYTE_SIZE, "byte", new byte[] {0}, 0),
  CHAR(true, DataSize.CHAR_SIZE, "char", new byte[] {0, 0}, (char) 0),
  SHORT(true, DataSize.SHORT_SIZE, "short", new byte[] {0, 0}, 0),
  INT(true, DataSize.INTEGER_SIZE, "int", new byte[] {0, 0, 0, 0}, 0),
  LONG(true, DataSize.LONG_SIZE, "long", new byte[] {0, 0, 0, 0, 0, 0, 0, 0}, 0),
  FLOAT(true, DataSize.FLOAT_SIZE, "float", new byte[] {0, 0, 0, 0}, 0),
  DOUBLE(true, DataSize.DOUBLE_SIZE, "double", new byte[] {0, 0, 0, 0, 0, 0, 0, 0}, 0),
  DATE(true, DataSize.DATE_SIZE, "Date", new byte[] {-1, -1, -1, -1, -1, -1, -1, -1}, null),
  STRING(false, -1, "String", new byte[] {DSCODE.NULL_STRING.toByte()}, null),
  OBJECT(false, -1, "Object", new byte[] {DSCODE.NULL.toByte()}, null),
  BOOLEAN_ARRAY(false, -1, "boolean[]", new byte[] {StaticSerialization.NULL_ARRAY}, null),
  CHAR_ARRAY(false, -1, "char[]", new byte[] {StaticSerialization.NULL_ARRAY}, null),
  BYTE_ARRAY(false, -1, "byte[]", new byte[] {StaticSerialization.NULL_ARRAY}, null),
  SHORT_ARRAY(false, -1, "short[]", new byte[] {StaticSerialization.NULL_ARRAY}, null),
  INT_ARRAY(false, -1, "int[]", new byte[] {StaticSerialization.NULL_ARRAY}, null),
  LONG_ARRAY(false, -1, "long[]", new byte[] {StaticSerialization.NULL_ARRAY}, null),
  FLOAT_ARRAY(false, -1, "float[]", new byte[] {StaticSerialization.NULL_ARRAY}, null),
  DOUBLE_ARRAY(false, -1, "double[]", new byte[] {StaticSerialization.NULL_ARRAY}, null),
  STRING_ARRAY(false, -1, "String[]", new byte[] {StaticSerialization.NULL_ARRAY}, null),
  OBJECT_ARRAY(false, -1, "Object[]", new byte[] {StaticSerialization.NULL_ARRAY}, null),
  ARRAY_OF_BYTE_ARRAYS(false, -1, "byte[][]", new byte[] {StaticSerialization.NULL_ARRAY}, null);

  private final boolean isFixedWidth;
  /**
   * For fixed width fields. All others have -1.
   */
  private final int width;
  private final String name;
  private final ByteBuffer defaultSerializedValue;
  private final Object defaultValue;

  private FieldType(boolean isFixedWidth, int width, String name, byte[] defaultBytes,
      Object defaultValue) {
    this.isFixedWidth = isFixedWidth;
    this.width = width;
    this.name = name;
    this.defaultSerializedValue = ByteBuffer.wrap(defaultBytes).asReadOnlyBuffer();
    this.defaultValue = defaultValue;
  }

  /**
   * Returns true if the type is "fixed-width"; false if it is "variable-width".
   */
  public boolean isFixedWidth() {
    return this.isFixedWidth;
  }

  /**
   * Returns the number of bytes used to serialize fixed-width fields; -1 is returned for
   * variable-width fields.
   */
  public int getWidth() {
    return this.width;
  }

  @Override
  public String toString() {
    return this.name;
  }

  /**
   * Returns a ByteBuffer that contains the serialized encoding of this type's default value.
   */
  public ByteBuffer getDefaultBytes() {
    return this.defaultSerializedValue;
  }

  /**
   * Given a Class return the corresponding FieldType.
   */
  public static FieldType get(Class<?> c) {
    if (c.equals(boolean.class)) {
      return BOOLEAN;
    } else if (c.equals(byte.class)) {
      return BYTE;
    } else if (c.equals(char.class)) {
      return CHAR;
    } else if (c.equals(short.class)) {
      return SHORT;
    } else if (c.equals(int.class)) {
      return INT;
    } else if (c.equals(long.class)) {
      return LONG;
    } else if (c.equals(float.class)) {
      return FLOAT;
    } else if (c.equals(double.class)) {
      return DOUBLE;
    } else if (c.equals(String.class)) {
      return STRING;
    } else if (c.equals(Date.class)) {
      return DATE;
    } else if (c.isArray()) {
      if (c.equals(boolean[].class)) {
        return BOOLEAN_ARRAY;
      } else if (c.equals(byte[].class)) {
        return BYTE_ARRAY;
      } else if (c.equals(char[].class)) {
        return CHAR_ARRAY;
      } else if (c.equals(short[].class)) {
        return SHORT_ARRAY;
      } else if (c.equals(int[].class)) {
        return INT_ARRAY;
      } else if (c.equals(long[].class)) {
        return LONG_ARRAY;
      } else if (c.equals(float[].class)) {
        return FLOAT_ARRAY;
      } else if (c.equals(double[].class)) {
        return DOUBLE_ARRAY;
      } else if (c.equals(String[].class)) {
        return STRING_ARRAY;
      } else if (c.equals(byte[][].class)) {
        return ARRAY_OF_BYTE_ARRAYS;
      } else {
        return OBJECT_ARRAY;
      }
    } else {
      return OBJECT;
    }
  }

  public Object getDefaultValue() {
    return defaultValue;
  }
}
