/**
 * 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 com.datatorrent.lib.appdata.schemas;

import java.io.Serializable;

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

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;

/**
 * This enum is used to represent data types throughout AppData Framework.
 * @since 3.0.0
 */
public enum Type implements Serializable
{
  /**
   * Boolean data type.
   */
  BOOLEAN("boolean", 1, JSONType.BOOLEAN, Boolean.class,
          Collections.unmodifiableSet(new HashSet<Type>())),
  /**
   * String data type.
   */
  STRING("string", -1, JSONType.STRING, String.class,
         Collections.unmodifiableSet(new HashSet<Type>())),
  /**
   * Char data type.
   */
  CHAR("char", 2, JSONType.STRING, Character.class,
       ImmutableSet.of(STRING)),
  /**
   * Double data type.
   */
  DOUBLE("double", 8, JSONType.NUMBER, Double.class,
         Collections.unmodifiableSet(new HashSet<Type>())),
  /**
   * Float data type.
   */
  FLOAT("float", 4, JSONType.NUMBER, Float.class,
        ImmutableSet.of(DOUBLE)),
  /**
   * Long data type.
   */
  LONG("long", 8, JSONType.NUMBER, Long.class,
       Collections.unmodifiableSet(new HashSet<Type>())),
  /**
   * Integer data type.
   */
  INTEGER("integer", 4, JSONType.NUMBER, Integer.class,
          ImmutableSet.of(LONG)),
  /**
   * Short data type.
   */
  SHORT("short", 2, JSONType.NUMBER, Short.class,
        ImmutableSet.of(INTEGER, LONG)),
  /**
   * Byte data type.
   */
  BYTE("byte", 1, JSONType.NUMBER, Byte.class,
       ImmutableSet.of(SHORT, INTEGER, LONG)),
  /**
   * Object data type.
   */
  OBJECT("object", -1, JSONType.INVALID, Object.class,
          Collections.unmodifiableSet(new HashSet<Type>()));

  /**
   * A set containing all the numeric types.
   */
  public static final Set<Type> NUMERIC_TYPES = ImmutableSet.of(BYTE, SHORT, INTEGER, LONG, FLOAT, DOUBLE);
  /**
   * A set containing all the non numeric types.
   */
  public static final Set<Type> NON_NUMERIC_TYPES = ImmutableSet.of(BOOLEAN, CHAR, STRING);
  /**
   * A map from the names to the types.
   */
  public static final Map<String, Type> NAME_TO_TYPE;
  /**
   * A map from a class representing the type to the type itself.
   */
  public static final Map<Class<?>, Type> CLASS_TO_TYPE;

  static {
    Map<String, Type> nameToType = Maps.newHashMap();

    for (Type type : Type.values()) {
      nameToType.put(type.getName(), type);
    }

    NAME_TO_TYPE = Collections.unmodifiableMap(nameToType);

    Map<Class<?>, Type> clazzToType = Maps.newHashMap();

    for (Type type : Type.values()) {
      clazzToType.put(type.getClazz(), type);
    }

    CLASS_TO_TYPE = Collections.unmodifiableMap(clazzToType);
  }

  /**
   * The name of the type.
   */
  private final String name;
  /**
   * The type of the corresponding JSON element.
   */
  private final JSONType jsonType;
  /**
   * Class of the corresponding Java type.
   */
  private final Class<?> clazz;
  /**
   * In the case of numeric types, there may be a "higher" type. For example
   * ints can be promoted to longs. This set holds all of the types that this
   * type could be promoted to. If this type cannot be promoted then this will be empty.
   */
  private final Set<Type> higherTypes;
  /**
   * The number of bytes required to store a value of this type. If a value of
   * this type can be of variable length then this would be -1.
   */
  private final int byteSize;

  /**
   * Creates a type enum.
   * @param name The name of the type.
   * @param byteSize The number of bytes a value of this type would occupy. -1 if variable length.
   * @param jsonType The type of corresponding json values.
   * @param clazz The Class of the corresponding Java type.
   * @param higherTypes The set of types to which this type can be promoted.
   */
  Type(String name, int byteSize, JSONType jsonType, Class<?> clazz, Set<Type> higherTypes)
  {
    this.name = name;
    this.byteSize = byteSize;
    this.jsonType = jsonType;
    this.clazz = clazz;
    this.higherTypes = higherTypes;
  }

  /**
   * Gets the name of the type.
   * @return The name of the type.
   */
  public String getName()
  {
    return name;
  }

  /**
   * Gets the byte size of the value.
   * @return The byte size of the value.
   */
  public int getByteSize()
  {
    return byteSize;
  }

  /**
   * Gets the corresponding JSONType of this type.
   * @return The corresponding JSONType of this type.
   */
  public JSONType getJSONType()
  {
    return jsonType;
  }

  /**
   * Gets the Java class corresponding to this type.
   * @return The Java class corresponding to this type.
   */
  public Class<?> getClazz()
  {
    return clazz;
  }

  /**
   * Gets the set of types to which this type can be promoted.
   * @return The set of types to which this type can be promoted.
   */
  public Set<Type> getHigherTypes()
  {
    return higherTypes;
  }

  /**
   * Determines if the given type is a higher type of this type.
   * @param type The type which may or not be a parent of this type.
   * @return True if the given type is a higher type of this type. False otherwise.
   */
  public boolean isChildOf(Type type)
  {
    return higherTypes.contains(type);
  }

  /**
   * Determines if one of the given types is a child of the other.
   * @param a This type will be checked to see if it is a child of b.
   * @param b This type will be checked to see if it is a child of a.
   * @return True if one of the given types is a child of the other. False otherwise.
   */
  public static boolean areRelated(Type a, Type b)
  {
    return a == b || a.isChildOf(b) || b.isChildOf(a);
  }

  /**
   * Gets the type corresponding to the given name.
   * @param name The name of the type.
   * @return The type corresponding to the name or null if there is no type
   * corresponding to the given name.
   */
  public static Type getType(String name)
  {
    return NAME_TO_TYPE.get(name);
  }

  public static Type getTypeEx(String name)
  {
    Type type = getType(name);

    Preconditions.checkArgument(type != null, name + " is not a valid type.");

    return type;
  }

  /**
   * Promotes the given object from the "from" type to the "to" type.
   * @param from The current type of the given object.
   * @param to The desired type for the given object.
   * @param o The object whose type must be converted.
   * @return The result of promoting the given object o to the "to" type.
   */
  public static Object promote(Type from, Type to, Object o)
  {
    if (from == to) {
      return o;
    }

    Preconditions.checkArgument(!(from == Type.BOOLEAN || from == Type.CHAR || from == Type.LONG
        || from == Type.DOUBLE), "Cannot convert " + Type.BOOLEAN.getName() + ", " + Type.CHAR.getName()
        + ", " + Type.LONG.getName() + ", or " + Type.DOUBLE + " to a larger type.");

    Preconditions.checkArgument(from.getHigherTypes().contains(to),
        from.getName() + " cannot be promoted to " + to.getName());

    if (from == Type.FLOAT && to == Type.DOUBLE) {
      return (Double)((Float)o).doubleValue();
    }

    if (from == Type.BYTE) {
      if (to == Type.SHORT) {
        return (Short)((Byte)o).shortValue();
      } else if (to == Type.INTEGER) {
        return (Integer)((Byte)o).intValue();
      } else if (to == Type.LONG) {
        return (Long)((Byte)o).longValue();
      }
    }

    if (from == Type.SHORT) {
      if (to == Type.INTEGER) {
        return (Integer)((Short)o).intValue();
      } else if (to == Type.LONG) {
        return (Long)((Short)o).longValue();
      }
    }

    if (from == Type.INTEGER
        && to == Type.LONG) {
      return (Long)((Integer)o).longValue();
    }

    throw new UnsupportedOperationException("This should not happen.");
  }
}
