package org.apache.samoa.instances;

/*
 * #%L
 * SAMOA
 * %%
 * Copyright (C) 2014 - 2015 Apache Software Foundation
 * %%
 * 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.
 * #L%
 */

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.avro.Schema;
import org.apache.avro.Schema.Field;
import org.apache.avro.generic.GenericData.EnumSymbol;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.io.DatumReader;

/**
 * Load Data from Avro Stream and parse to corresponding Dense & Parse Instances Abstract Class: Subclass this class for
 * different types of Avro Encodings
 *
 */
public abstract class AvroLoader implements Loader {

  private static final long serialVersionUID = 1L;

  /** Representation of the Avro Schema for the Instances being read. Built from the first line in the data */
  protected Schema schema = null;

  /** Meta-data of the Instance */
  protected InstanceInformation instanceInformation;

  /** List of attributes in the data as read from the schema */
  protected List<Attribute> attributes;

  /** This variable is to check if the data stored is Sparse or Dense */
  protected boolean isSparseData;

  protected int classAttribute;

  /** Datum Reader for Avro Data */
  public DatumReader<GenericRecord> datumReader = null;

  public AvroLoader(int classAttribute) {
    this.classAttribute = classAttribute;
    this.isSparseData = false;
  }

  /** Intialize Avro Schema, Meta Data, InstanceInformation from Input Avro Stream */
  public abstract void initializeSchema(InputStream inputStream);

  /** Read a single SAMOA Instance from Input Avro Stream */
  public abstract Instance readInstance();

  /**
   * Method to read Dense Instances from Avro File
   * 
   * @return Instance
   */
  protected Instance readInstanceDense(GenericRecord record)
  {
    Instance instance = new DenseInstance(this.instanceInformation.numAttributes() + 1);
    int numAttribute = 0;

    for (Attribute attribute : attributes) {
      Object value = record.get(attribute.name);

      boolean isNumeric = attributes.get(numAttribute).isNumeric();
      boolean isNominal = attributes.get(numAttribute).isNominal();

      if (isNumeric)
      {
        if (value instanceof Double)
          this.setDenseValue(instance, numAttribute, (double) value);
        else if (value instanceof Long)
          this.setDenseValue(instance, numAttribute, (long) value);
        else if (value instanceof Integer)
          this.setDenseValue(instance, numAttribute, (int) value);
        else
          throw new RuntimeException("Invalid data type in the Avro data for Numeric Type : " + attribute.name);
      }
      else if (isNominal)
      {
        double valueAttribute;

        if (!(value instanceof EnumSymbol))
          throw new RuntimeException("Invalid data type in the Avro data for Nominal Type : " + attribute.name);

        EnumSymbol enumSymbolalue = (EnumSymbol) value;

        String stringValue = enumSymbolalue.toString();

        if (("?".equals(stringValue)) || (stringValue == null)) {
          valueAttribute = Double.NaN;
        } else {
          valueAttribute = this.instanceInformation.attribute(numAttribute).indexOfValue(stringValue);
        }

        this.setDenseValue(instance, numAttribute, valueAttribute);
      }
      numAttribute++;
    }

    return (numAttribute > 0) ? instance : null;

  }

  /**
   * Sets a Dense Value in the corresponding attribute index
   * 
   * @param instance
   *          is the Instance where values will be set
   * @param numAttribute
   *          is the index of the attribute
   * @param valueAttribute
   *          is the value of the attribute for this Instance
   */

  private void setDenseValue(Instance instance, int numAttribute, double valueAttribute) {

    if (this.instanceInformation.classIndex() == numAttribute)
      instance.setClassValue(valueAttribute);
    else
      instance.setValue(numAttribute, valueAttribute);
  }

  /**
   * Method to read Sparse Instances from Avro File
   * 
   * @return Instance
   */
  protected Instance readInstanceSparse(GenericRecord record) {

    Instance instance = new SparseInstance(1.0, null);
    int numAttribute = -1;
    ArrayList<Double> attributeValues = new ArrayList<Double>();
    List<Integer> indexValues = new ArrayList<Integer>();

    for (Attribute attribute : attributes) {
      numAttribute++;
      Object value = record.get(attribute.name);

      boolean isNumeric = attributes.get(numAttribute).isNumeric();
      boolean isNominal = attributes.get(numAttribute).isNominal();

      /** If value is empty/null iterate to the next attribute. **/
      if (value == null)
        continue;

      if (isNumeric)
      {
        if (value instanceof Double)
          this.setSparseValue(instance, indexValues, attributeValues, numAttribute, (double) value);
        else if (value instanceof Long)
          this.setSparseValue(instance, indexValues, attributeValues, numAttribute, (long) value);
        else if (value instanceof Integer)
          this.setSparseValue(instance, indexValues, attributeValues, numAttribute, (int) value);
        else
          throw new RuntimeException(AVRO_LOADER_INVALID_TYPE_ERROR + " : " + attribute.name);
      }
      else if (isNominal)
      {
        double valueAttribute;

        if (!(value instanceof EnumSymbol))
          throw new RuntimeException(AVRO_LOADER_INVALID_TYPE_ERROR + " : " + attribute.name);

        EnumSymbol enumSymbolalue = (EnumSymbol) value;

        String stringValue = enumSymbolalue.toString();

        if (("?".equals(stringValue)) || (stringValue == null)) {
          valueAttribute = Double.NaN;
        } else {
          valueAttribute = this.instanceInformation.attribute(numAttribute).indexOfValue(stringValue);
        }

        this.setSparseValue(instance, indexValues, attributeValues, numAttribute, valueAttribute);
      }
    }

    int[] arrayIndexValues = new int[attributeValues.size()];
    double[] arrayAttributeValues = new double[attributeValues.size()];

    for (int i = 0; i < arrayIndexValues.length; i++) {
      arrayIndexValues[i] = indexValues.get(i).intValue();
      arrayAttributeValues[i] = attributeValues.get(i).doubleValue();
    }

    instance.addSparseValues(arrayIndexValues, arrayAttributeValues, this.instanceInformation.numAttributes());
    return instance;

  }

  /**
   * Sets a Sparse Value in the corresponding attribute index
   * 
   * @param instance
   *          is the Instance where values will be set
   * @param indexValues
   *          is the list of Index values
   * @param attributeValues
   *          is the list of Attribute values
   * @param numAttribute
   *          is the index of the attribute
   * @param valueAttribute
   *          is the value of the attribute for this Instance
   */
  private void setSparseValue(Instance instance, List<Integer> indexValues, List<Double> attributeValues,
      int numAttribute, double valueAttribute) {

    if (this.instanceInformation.classIndex() == numAttribute) {
      instance.setClassValue(valueAttribute);
    } else {
      indexValues.add(numAttribute);
      attributeValues.add(valueAttribute);
    }
  }

  /**
   * Builds the Meta Data of from the Avro Schema
   * 
   * @return
   */
  protected InstanceInformation getHeader() {

    String relation = schema.getName();
    attributes = new ArrayList<Attribute>();

    /** By Definition, the returned list is in the order of their positions. **/
    List<Schema.Field> fields = schema.getFields();

    for (Field field : fields) {
      Schema attributeSchema = field.schema();

      /** Currently SAMOA supports only NOMINAL & Numeric Types. **/
      if (attributeSchema.getType() == Schema.Type.ENUM)
      {
        List<String> attributeLabels = attributeSchema.getEnumSymbols();
        attributes.add(new Attribute(field.name(), attributeLabels));
      }
      else
        attributes.add(new Attribute(field.name()));
    }
    return new InstanceInformation(relation, attributes);
  }

  /**
   * Identifies if the dataset is is Sparse or Dense
   * 
   * @return boolean
   */
  protected boolean isSparseData()
  {
    List<Schema.Field> fields = schema.getFields();
    for (Field field : fields) {
      Schema attributeSchema = field.schema();

      /** If even one attribute has a null union (nullable attribute) consider it as sparse data **/
      if (attributeSchema.getType() == Schema.Type.UNION)
      {
        List<Schema> unionTypes = attributeSchema.getTypes();
        for (Schema unionSchema : unionTypes) {
          if (unionSchema.getType() == Schema.Type.NULL)
            return true;
        }
      }

    }
    return false;
  }

  @Override
  public InstanceInformation getStructure() {
    return this.instanceInformation;
  }

  /** Error Messages to for all types of Avro Loaders */
  protected static final String AVRO_LOADER_INVALID_TYPE_ERROR = "Invalid data type in the Avro data";
  protected static final String AVRO_LOADER_SCHEMA_READ_ERROR = "Exception while reading the schema from Avro File";
  protected static final String AVRO_LOADER_INSTANCE_READ_ERROR = "Exception while reading the Instance from Avro File.";
}
