/**
 * 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.contrib.mongodb;

import com.datatorrent.lib.util.PojoUtils;
import com.datatorrent.lib.util.PojoUtils.Getter;
import com.mongodb.BasicDBObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.validation.constraints.NotNull;

import org.apache.hadoop.classification.InterfaceStability.Evolving;

/**
 * Implementation of {@link MongoDBOutputOperator} that saves a POJO in the mongodb database. <br/>
 * <p>
 * @displayName MongoDb Output Operator
 * @category Output
 * @tags database, nosql, pojo, mongodb
 * @since 0.3.5
 */
@Evolving
public class MongoDBPOJOOutputOperator extends MongoDBOutputOperator<Object>
{
  private final transient ArrayList<Getter<Object, Object>> getterValues;
  @NotNull
  private ArrayList<String> keys;
  @NotNull
  private ArrayList<String> expressions;
  private static final Map<String, Class<?>> mapPrimitives = new HashMap<String, Class<?>>();
  private final transient Map<String, String[]> nestedKeys;
  @NotNull
  private transient ArrayList<String> tablenames;
  @NotNull
  private ArrayList<String> fieldTypes;

  /*
   * An ArrayList of expressions to get field values from POJO and populate mongodb.
   */
  public ArrayList<String> getExpressions()
  {
    return expressions;
  }

  public void setExpressions(ArrayList<String> expressions)
  {
    this.expressions = expressions;
  }

  /*
   * ArrayList of Data Types of Keys specified by user in same order as Keys.
   * User needs to specify the java package also for non primitive data types.
   * Example: java.lang.String,int,char,java.lang.Integer,java.util.Map
   */
  public ArrayList<String> getFieldTypes()
  {
    return fieldTypes;
  }

  public void setFieldTypes(ArrayList<String> fieldTypes)
  {
    this.fieldTypes = fieldTypes;
  }

  /*
   * Keys to be stored in mongodb document.Example: Id,name,address.
   */
  public ArrayList<String> getKeys()
  {
    return keys;
  }

  public void setKeys(ArrayList<String> keys)
  {
    this.keys = keys;
  }

  /*
   * Fields can be stored in separate tables in the same database.This is the list of tables.
   */
  public ArrayList<String> getTablenames()
  {
    return tablenames;
  }

  public void setTablenames(ArrayList<String> tablenames)
  {
    this.tablenames = tablenames;
  }

  public MongoDBPOJOOutputOperator()
  {
    super();
    getterValues = new ArrayList<Getter<Object, Object>>();
    nestedKeys = new HashMap<String, String[]>();
  }

  static
  {
    mapPrimitives.put("boolean", boolean.class);
    mapPrimitives.put("char", char.class);
    mapPrimitives.put("short", short.class);
    mapPrimitives.put("int", int.class);
    mapPrimitives.put("long", long.class);
    mapPrimitives.put("float", float.class);
    mapPrimitives.put("double", double.class);
  }

  private void processFirstTuple(Object tuple)
  {
    ArrayList<Class<?>> classTypes = new ArrayList<Class<?>>();
    for (String fieldType: fieldTypes) {
      if (mapPrimitives.containsKey(fieldType)) {
        classTypes.add(mapPrimitives.get(fieldType));
      }
      else {
        try {
          classTypes.add(Class.forName(fieldType));
        }
        catch (ClassNotFoundException ex) {
          throw new RuntimeException(ex);
        }
      }
    }
    final Class<?> fqcn = tuple.getClass();
    for (int i = 0; i < expressions.size(); i++) {
      final String key = keys.get(i);
      getterValues.add(PojoUtils.createGetter(fqcn, expressions.get(i), classTypes.get(i)));
      if (key.contains(".")) {
        nestedKeys.put(key, key.split("[.]"));
      }
      String table = tablenames.get(i);
      if(!tableList.contains(table)){
        tableList.add(table);
      }
    }

  }

  @Override
  public void processTuple(Object tuple)
  {
    tableToDocument.clear();
    BasicDBObject doc;
    BasicDBObject nestedDoc = null;

    if (getterValues.isEmpty()) {
      processFirstTuple(tuple);
    }

    for (int i = 0; i < keys.size(); i++) {
      String key = keys.get(i);
      String table = tablenames.get(i);
      //nested object are stored in a new document in mongo db.
      if (key.contains(".")) {
        String[] subKeys = nestedKeys.get(key);
        if (nestedDoc == null) {
          nestedDoc = new BasicDBObject();
        }
        nestedDoc.put(subKeys[1], (getterValues.get(i)).get(tuple));
        if ((doc = tableToDocument.get(table)) == null) {
          doc = new BasicDBObject();
        }
        if (doc.containsField(subKeys[0])) {
          doc.append(subKeys[0], nestedDoc);
        }
        else {
          doc.put(subKeys[0], nestedDoc);
        }
      }
      else {
        if ((doc = tableToDocument.get(table)) == null) {
          doc = new BasicDBObject();
        }
        doc.put(key, (getterValues.get(i)).get(tuple));
      }
      tableToDocument.put(table, doc);
    }
    processTupleCommon();

  }

  /*
   *This function is not required in POJO based implementation of MongoDBOutputOperator.
   */
  @Override
  public void setColumnMapping(String[] mapping)
  {
  }

}
