/*
 * Copyright (c) 2010-2013, 2015 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Ibrahim Sallam - initial API and implementation
 */
package org.eclipse.emf.cdo.server.internal.objectivity.mapper;

import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.server.internal.objectivity.bundle.OM;
import org.eclipse.emf.cdo.server.internal.objectivity.db.ObjyObject;
import org.eclipse.emf.cdo.server.internal.objectivity.db.ObjySchema;

import org.eclipse.net4j.util.om.trace.ContextTracer;

import org.eclipse.emf.ecore.EStructuralFeature;

import com.objy.as.app.Class_Object;
import com.objy.as.app.Numeric_Value;
import com.objy.as.app.Proposed_Basic_Attribute;
import com.objy.as.app.Proposed_Class;
import com.objy.as.app.Proposed_Property;
import com.objy.as.app.VArray_Object;
import com.objy.as.app.d_Access_Kind;
import com.objy.as.app.d_Attribute;
import com.objy.as.app.d_Class;
import com.objy.as.app.d_Module;
import com.objy.as.app.ooBaseType;

import java.util.Date;

/**
 * @author Ibrahim Sallam
 */
public abstract class NumericManyTypeMapper extends BasicTypeMapper implements IManyTypeMapper
{

  protected abstract Object fromNumericValue(Numeric_Value numericValue, boolean isNull);

  protected abstract Numeric_Value toNumericValue(Object value);

  protected abstract ooBaseType getObjyBaseType();

  private static final ContextTracer TRACER_DEBUG = new ContextTracer(OM.DEBUG, NumericManyTypeMapper.class);

  public static NumericManyTypeMapper.TMBoolean TMBOOLEAN = new TMBoolean();

  public static NumericManyTypeMapper.TMByte TMBYTE = new TMByte();

  public static NumericManyTypeMapper.TMChar TMCHAR = new TMChar();

  public static NumericManyTypeMapper.TMDate TMDATE = new TMDate();

  public static NumericManyTypeMapper.TMDouble TMDOUBLE = new TMDouble();

  public static NumericManyTypeMapper.TMFloat TMFLOAT = new TMFloat();

  public static NumericManyTypeMapper.TMInteger TMINTEGER = new TMInteger();

  public static NumericManyTypeMapper.TMLong TMLONG = new TMLong();

  public static NumericManyTypeMapper.TMShort TMSHORT = new TMShort();

  // ---------------------------------
  // Schema
  // ---------------------------------

  private String embeddedClassName()
  {
    return "oo_" + getObjyBaseType() + "_Class";
  }

  private d_Class getEmbeddedClass()
  {
    d_Class embeddedClass = ObjySchema.getTopModule().resolve_class(embeddedClassName());
    // System.out.println("OBJY: Resolving className: " + embeddedClassName() + " - d_Class: " + embeddedClass);
    return embeddedClass;
  }

  private boolean createEmbeddedClass()
  {
    boolean bDone = true;

    d_Module top_mod = ObjySchema.getTopModule();
    boolean inProcess = top_mod.proposed_classes().hasNext();

    Proposed_Class propClass = top_mod.propose_new_class(embeddedClassName());

    propClass.add_basic_attribute(com.objy.as.app.d_Module.LAST, d_Access_Kind.d_PUBLIC, // Access kind
        embeddedAttributeName, // Attribute name
        1, // # elements in fixed-size array
        getObjyBaseType() // Type of numeric data
    ); // Default value

    propClass.add_basic_attribute(com.objy.as.app.d_Module.LAST, d_Access_Kind.d_PUBLIC, // Access kind
        embeddedAttributeNull, // Attribute name
        1, // # elements in fixed-size array
        ooBaseType.ooBOOLEAN// Type of numeric data
    ); // Default value

    // System.out.println("OBJY: Propose Creating new class: " + embeddedClassName());

    // ObjySchema.getTopModule().propose_new_class(propClass);
    if (!inProcess)
    {
      top_mod.activate_proposals(true, true);
    }

    return bDone;
  }

  /**
   *
   */
  public boolean createSchema(Proposed_Class proposedClass, EStructuralFeature feature)
  {
    if (TRACER_DEBUG.isEnabled())
    {
      TRACER_DEBUG.trace("Adding attribute " + feature.getName() + "  " + this.getClass().getName());
    }

    // create an embedded class (attributeType, attributeIsNull).
    // TODO - we might need to move this to the .objectivity.schema, since it's
    // independent of the model classes.

    if (getEmbeddedClass() == null && !createEmbeddedClass())
    {
      return false;
    }

    // create array of embedded class type.
    proposedClass.add_varray_attribute(com.objy.as.app.d_Module.LAST, d_Access_Kind.d_PUBLIC, // Access kind
        getAttributeName(feature), // Attribute name
        1, embeddedClassName());

    return false;
  }

  /**
   * TODO - this is a simple change to the attribute, make it handle more complex cases. I also don't think it does
   * handle the arrays.
   *
   * @param proposedooClass
   * @param feature
   */
  public void modifySchema(Proposed_Class proposedooClass, EStructuralFeature feature)
  {
    Proposed_Property prop = proposedooClass.resolve_property(getAttributeName(feature));

    if (prop instanceof Proposed_Basic_Attribute)
    {
      Proposed_Basic_Attribute attr = (Proposed_Basic_Attribute)prop;
      attr.change_base_type(getObjyBaseType());
    }
  }

  /**
   * TBD - Fixed size array attributes can't be accessed, so we can't validate This!!! OFJ (Fix it)
   */
  public boolean validate(d_Attribute dAttribute, EStructuralFeature feature)
  {
    System.out.println(">>>OBJYIMPL: NumericManyTypeMapper.validate() - not implemented.");
    return true;
    // d_Class varrayClass = dAttribute.class_type_of();
    // d_Class embeddedClass = varrayClass.
    // Class_Position position = embeddedClass.position_in_class(getAttributeName(feature));
    // //d_Type type = ooAttribute.type_of();
    // d_Type type = embeddedClass.attribute_at_position(position).type_of();
    // if (TRACER_DEBUG.isEnabled()) {
    // TRACER_DEBUG.trace(getAttributeName(feature) + " "
    // + ((Basic_Type) type).base_type() + " basic type "
    // + type.is_basic_type() + " - " + getObjyBaseType());
    // }
    // return type.is_basic_type()
    // && ((Basic_Type) type).base_type() == getObjyBaseType();
  }

  // ---------------------------------
  // Object
  // ---------------------------------

  public void setValue(ObjyObject objyObject, EStructuralFeature feature, int index, Object newValue)
  {
    // System.out.println("OBJY: Set value in VArray at index: "+ index + " - value: " + newValue);
    boolean isNull = newValue == null;
    Numeric_Value numericValue = toNumericValue(newValue);
    Numeric_Value isNullValue = isNull ? numericTrue : numericFalse;

    Class_Object embedded = getArray(objyObject, feature).get_class_obj(index);

    embedded.set_numeric(valueAttributePosition, numericValue);
    embedded.set_numeric(nullAttributePosition, isNullValue);
  }

  // get a single object/value at index.
  public Object getValue(ObjyObject objyObject, EStructuralFeature feature, int index)
  {
    Numeric_Value numericValue = null;

    Class_Object embedded = getArray(objyObject, feature).get_class_obj(index);

    numericValue = embedded.get_numeric(valueAttributePosition);
    boolean isNull = embedded.get_numeric(nullAttributePosition).booleanValue();

    return fromNumericValue(numericValue, isNull);
  }

  // remove a single value at index, it will set the value to default, and mark it
  // as "null", i.e. unset.
  public Object remove(ObjyObject objyObject, EStructuralFeature feature, int index)
  {
    // we'll just get the original value, and set the value to null.
    // Numeric_Value numericValue = null;

    long size = (int)getArray(objyObject, feature).size();
    for (int i = index; i < size - 1; i++)
    {
      setValue(objyObject, feature, i, getValue(objyObject, feature, i + 1));
    }
    // resize the array.
    getArray(objyObject, feature).resize(size - 1);
    /*
     * Class_Object embedded = getArray(objyObject, feature).get_class_obj(index); numericValue =
     * embedded.get_numeric(valueAttributePosition); boolean isNull =
     * embedded.get_numeric(nullAttributePosition).booleanValue(); Object oldValue = fromNumericValue(numericValue,
     * isNull); numericValue = toNumericValue(null); embedded.set_numeric(valueAttributePosition, numericValue);
     * embedded.set_numeric(nullAttributePosition, numericTrue);
     */
    return null;
  }

  // add value at index (extend the collection size).
  public void add(ObjyObject objyObject, EStructuralFeature feature, int index, Object value)
  {
    int arraySize = size(objyObject, feature);
    // System.out.println("OBJY: Adding object inside VArray at index: "+ index + " - value: " + value);
    if (index < arraySize - 1)
    {
      // throw new UnsupportedOperationException("adding object inside VArray?!!... Implement Me!!!");
      // resize the VArray.
      VArray_Object array = getArray(objyObject, feature);
      array.resize(arraySize + 1);
      for (int i = arraySize; i > index; i--)
      {
        Class_Object newEmbedded = array.get_class_obj(i);
        Class_Object oldEmbedded = array.get_class_obj(i - 1);
        newEmbedded.set_numeric(valueAttributePosition, oldEmbedded.get_numeric(valueAttributePosition));
        newEmbedded.set_numeric(nullAttributePosition, oldEmbedded.get_numeric(nullAttributePosition));
      }
    }
    if (index != -1 && index > arraySize)
    {
      throw new UnsupportedOperationException("adding object beyond VArray size()?!!... Implement Me!!!");
    }

    getArray(objyObject, feature).resize(arraySize + 1);

    setValue(objyObject, feature, index, value);
  }

  public// add all objects starting from an index. (extend the collection size).
  void addAll(ObjyObject objyObject, EStructuralFeature feature, int index, Object[] values)
  {
    // System.out.println("OBJY: AddAll objects inside VArray at index: "+ index + " - values: " + values);
    int arraySize = size(objyObject, feature);
    if (index < arraySize - 1)
    {
      throw new UnsupportedOperationException("adding objects inside VArray?!!... Implement Me!!!");
    }

    if (index != -1 && index > arraySize)
    {
      throw new UnsupportedOperationException("adding objects beyond VArray size()?!!... Implement Me!!!");
    }

    int newSize = arraySize + values.length;
    getArray(objyObject, feature).resize(newSize);

    for (int i = 0; i < values.length; i++)
    {
      setValue(objyObject, feature, arraySize + i, values[i]);
    }
  }

  // clear all collection.
  public void clear(ObjyObject objyObject, EStructuralFeature feature)
  {
    // set the varray size to 0.
    getArray(objyObject, feature).resize(0);
  }

  // this is similar to addAll, but it replaces the existing ones.
  public void setAll(ObjyObject objyObject, EStructuralFeature feature, int index, Object[] newValues)
  {

    VArray_Object array = getArray(objyObject, feature);

    array.resize(newValues.length);
    for (int i = 0; i < newValues.length; i++)
    {
      // TODO - we might need to optimize this!!!
      setValue(objyObject, feature, i, newValues[i]);
    }
  }

  // get all objects/values starting from an index.
  public Object[] getAll(ObjyObject objyObject, EStructuralFeature feature, int index, int chunkSize)
  {
    int size = size(objyObject, feature);

    if (chunkSize != CDORevision.UNCHUNKED)
    {
      size = Math.min(size, chunkSize);
    }

    Object[] values = new Object[size];

    // TODO - we might need to optimize this!!!!
    for (int i = 0; i < size; i++)
    {
      values[i] = getValue(objyObject, feature, i + index);
    }
    return values;
  }

  // return the size of the collection.
  public int size(ObjyObject objyObject, EStructuralFeature feature)
  {
    return (int)getArray(objyObject, feature).size();
  }

  public void delete(ObjyObject objyObject, EStructuralFeature feature)
  {
    throw new UnsupportedOperationException("Implement me!!");
  }

  public void move(ObjyObject objyObject, EStructuralFeature feature, int targetIndex, int sourceIndex)
  {
    if (targetIndex == sourceIndex)
    {
      return;
    }

    // get the object at sourceIndex.
    Object value = getValue(objyObject, feature, sourceIndex);

    // long size = (int)getArray(objyObject, feature).size();
    // TODO - check boundaries...

    if (sourceIndex > targetIndex)
    {
      for (int i = sourceIndex; i > targetIndex; i--)
      {
        setValue(objyObject, feature, i, getValue(objyObject, feature, i - 1));
      }
    }
    else if (sourceIndex < targetIndex)
    {
      for (int i = sourceIndex; i < targetIndex; i++)
      {
        setValue(objyObject, feature, i, getValue(objyObject, feature, i + 1));
      }
    }
    // set the saved value at target
    setValue(objyObject, feature, targetIndex, value);

  }

  public void initialize(Class_Object classObject, EStructuralFeature feature)
  {
    // TODO - verify if we need to do any initialization!!!
  }

  protected VArray_Object getArray(ObjyObject objyObject, EStructuralFeature feature)
  {
    // Class_Position position = getAttributePosition(objyObject, feature);
    String attributeName = getAttributeName(feature);
    return objyObject.get_varray(attributeName/* position */);
  }

  // ------------------------------------------------------------------------
  // ------------------- Various types --------------------------
  // ------------------------------------------------------------------------

  // ---------------------------
  // Boolean
  // ---------------------------
  public static class TMBoolean extends NumericManyTypeMapper
  {
    @Override
    protected ooBaseType getObjyBaseType()
    {
      return ooBaseType.ooBOOLEAN;
    }

    @Override
    protected Object fromNumericValue(Numeric_Value numericValue, boolean isNull)
    {
      Boolean value = null;
      if (!isNull)
      {
        value = numericValue.booleanValue();
      }
      return value;
    }

    @Override
    protected Numeric_Value toNumericValue(Object value)
    {
      if (value == null)
      {
        return new Numeric_Value(false);
      }

      return new Numeric_Value(((Boolean)value).booleanValue());
    }
  }

  // ---------------------------
  // Byte
  // ---------------------------
  public static class TMByte extends NumericManyTypeMapper
  {
    @Override
    public ooBaseType getObjyBaseType()
    {
      return ooBaseType.ooINT8;
    }

    @Override
    protected Object fromNumericValue(Numeric_Value numericValue, boolean isNull)
    {
      Byte value = null;
      if (!isNull)
      {
        value = numericValue.byteValue();
      }
      return value;

    }

    @Override
    protected Numeric_Value toNumericValue(Object value)
    {
      if (value == null)
      {
        return new Numeric_Value(0);
      }

      return new Numeric_Value(((Byte)value).byteValue());
    }
  }

  // ---------------------------
  // Char
  // ---------------------------
  public static class TMChar extends NumericManyTypeMapper
  {
    @Override
    public ooBaseType getObjyBaseType()
    {
      return ooBaseType.ooINT8;
    }

    @Override
    protected Object fromNumericValue(Numeric_Value numericValue, boolean isNull)
    {
      Character value = null;
      if (!isNull)
      {
        value = numericValue.charValue();
      }
      return value;

    }

    @Override
    protected Numeric_Value toNumericValue(Object value)
    {
      if (value == null)
      {
        return new Numeric_Value(0);
      }

      return new Numeric_Value(((Character)value).charValue());
    }
  }

  // ---------------------------
  // Date
  // ---------------------------
  public static class TMDate extends NumericManyTypeMapper
  {
    @Override
    public ooBaseType getObjyBaseType()
    {
      return ooBaseType.ooINT64;
    }

    @Override
    protected Object fromNumericValue(Numeric_Value numericValue, boolean isNull)
    {
      Date value = null;
      if (!isNull)
      {
        value = new Date(numericValue.longValue());
      }
      return value;

    }

    @Override
    protected Numeric_Value toNumericValue(Object value)
    {
      if (value == null)
      {
        return new Numeric_Value(0);
      }

      return new Numeric_Value(((Date)value).getTime());
    }
  }

  // ---------------------------
  // Double
  // ---------------------------
  public static class TMDouble extends NumericManyTypeMapper
  {
    @Override
    public ooBaseType getObjyBaseType()
    {
      return ooBaseType.ooFLOAT64;
    }

    @Override
    protected Object fromNumericValue(Numeric_Value numericValue, boolean isNull)
    {
      Double value = null;
      if (!isNull)
      {
        value = numericValue.doubleValue();
      }
      return value;

    }

    @Override
    protected Numeric_Value toNumericValue(Object value)
    {
      if (value == null)
      {
        return new Numeric_Value(0.0);
      }

      return new Numeric_Value(((Double)value).doubleValue());
    }
  }

  // ---------------------------
  // Float
  // ---------------------------
  public static class TMFloat extends NumericManyTypeMapper
  {
    @Override
    protected ooBaseType getObjyBaseType()
    {
      return ooBaseType.ooFLOAT64;
    }

    @Override
    protected Object fromNumericValue(Numeric_Value numericValue, boolean isNull)
    {
      Float value = null;
      if (!isNull)
      {
        value = numericValue.floatValue();
      }
      return value;

    }

    @Override
    protected Numeric_Value toNumericValue(Object value)
    {
      if (value == null)
      {
        return new Numeric_Value(0.0);
      }

      return new Numeric_Value(((Float)value).floatValue());
    }
  }

  // ---------------------------
  // Integer
  // ---------------------------
  public static class TMInteger extends NumericManyTypeMapper
  {
    @Override
    public ooBaseType getObjyBaseType()
    {
      return ooBaseType.ooINT32;
    }

    @Override
    protected Object fromNumericValue(Numeric_Value numericValue, boolean isNull)
    {
      Integer value = null;
      if (!isNull)
      {
        value = numericValue.intValue();
      }
      return value;
    }

    @Override
    protected Numeric_Value toNumericValue(Object value)
    {
      if (value == null)
      {
        return new Numeric_Value(0);
      }

      return new Numeric_Value(((Integer)value).intValue());
    }
  }

  // ---------------------------
  // Long
  // ---------------------------
  public static class TMLong extends NumericManyTypeMapper
  {
    @Override
    public ooBaseType getObjyBaseType()
    {
      return ooBaseType.ooINT64;
    }

    @Override
    protected Object fromNumericValue(Numeric_Value numericValue, boolean isNull)
    {
      Long value = null;
      if (!isNull)
      {
        value = numericValue.longValue();
      }
      return value;

    }

    @Override
    protected Numeric_Value toNumericValue(Object value)
    {
      if (value == null)
      {
        return new Numeric_Value(0);
      }

      return new Numeric_Value(((Long)value).longValue());
    }
  }

  // ---------------------------
  // Short
  // ---------------------------
  public static class TMShort extends NumericManyTypeMapper
  {
    @Override
    public ooBaseType getObjyBaseType()
    {
      return ooBaseType.ooINT16;
    }

    @Override
    protected Object fromNumericValue(Numeric_Value numericValue, boolean isNull)
    {
      Short value = null;
      if (!isNull)
      {
        value = numericValue.shortValue();
      }
      return value;
    }

    @Override
    protected Numeric_Value toNumericValue(Object value)
    {
      if (value == null)
      {
        return new Numeric_Value(0);
      }

      return new Numeric_Value(((Short)value).shortValue());
    }
  }

}
