/*
 * Copyright (c) 2013 Malhar Inc. ALL Rights Reserved.
 *
 * 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.
 */
package com.datatorrent.lib.math;

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

import org.apache.commons.lang.mutable.MutableDouble;

import com.datatorrent.api.DefaultInputPort;
import com.datatorrent.api.DefaultOutputPort;
import com.datatorrent.api.StreamCodec;
import com.datatorrent.api.annotation.InputPortFieldAnnotation;
import com.datatorrent.api.annotation.OutputPortFieldAnnotation;
import com.datatorrent.lib.util.BaseNumberKeyValueOperator;
import com.datatorrent.lib.util.KeyValPair;

/**
 *
 * Emits the sum of values for each key at the end of window. <p> This is an end window operator. Default unifier works as this operator follows sticky partition.<br> <br> <b>Ports</b>:<br>
 * <b>data</b>: expects KeyValPair&lt;K,V extends Number&gt;<br> <b>sum</b>: emits KeyValPair&lt;K,V extends Number&gt;<br> <br> <b>Properties</b>:<br> <b>inverse</b>: If set to true the key in the
 * filter will block tuple<br> <b>filterBy</b>: List of keys to filter on<br>
 * <b>cumulative</b>: boolean flag, if set the sum is not cleared at the end of window, <br>
 * hence generating cumulative sum
 * across streaming windows. Default is false.<br>
 * <br>
 *
 * @since 0.3.2
 */
public class SumKeyVal<K, V extends Number> extends BaseNumberKeyValueOperator<K, V>
{
  protected class SumEntry
  {
    public MutableDouble sum;
    public boolean changed = true;

    SumEntry()
    {
    }

    SumEntry(MutableDouble sum, boolean changed)
    {
      this.sum = sum;
      this.changed = changed;
    }

  }

  /**
   * Sums key map.
   */
  protected HashMap<K, SumEntry> sums = new HashMap<K, SumEntry>();
  
  /**
   * Cumulative sum flag.
   */
  protected boolean cumulative = false;
  
  /**
   * Input port to receive data.
   */
  @InputPortFieldAnnotation(name = "data")
  public final transient DefaultInputPort<KeyValPair<K, V>> data = new DefaultInputPort<KeyValPair<K, V>>()
  {
    /**
     * For each tuple (a key value pair) Adds the values for each key.
     */
    @Override
    public void process(KeyValPair<K, V> tuple)
    {
      K key = tuple.getKey();
      if (!doprocessKey(key)) {
        return;
      }
      SumEntry val = sums.get(key);
      if (val == null) {
        val = new SumEntry(new MutableDouble(tuple.getValue().doubleValue()), true);
      }
      else {
        val.sum.add(tuple.getValue().doubleValue());
        val.changed = true;
      }
      sums.put(cloneKey(key), val);
    }

    /**
     * Stream codec used for partitioning.
     */
    @Override
    public Class<? extends StreamCodec<KeyValPair<K, V>>> getStreamCodec()
    {
      return getKeyValPairStreamCodec();
    }

  };
  
  /**
   * Output sum port.
   */
  @OutputPortFieldAnnotation(name = "sum", optional = true)
  public final transient DefaultOutputPort<KeyValPair<K, V>> sum = new DefaultOutputPort<KeyValPair<K, V>>();
  
  /**
   * Output double sum port.
   */
  @OutputPortFieldAnnotation(name = "sumDouble", optional = true)
  public final transient DefaultOutputPort<KeyValPair<K, Double>> sumDouble = new DefaultOutputPort<KeyValPair<K, Double>>();
  
  /** 
   * Output integer sum port.
   */
  @OutputPortFieldAnnotation(name = "sumInteger", optional = true)
  public final transient DefaultOutputPort<KeyValPair<K, Integer>> sumInteger = new DefaultOutputPort<KeyValPair<K, Integer>>();
  
  /**
   * Output long sum port.
   */
  @OutputPortFieldAnnotation(name = "sumLong", optional = true)
  public final transient DefaultOutputPort<KeyValPair<K, Long>> sumLong = new DefaultOutputPort<KeyValPair<K, Long>>();
  
  /**
   * Output short sum port.
   */
  @OutputPortFieldAnnotation(name = "sumShort", optional = true)
  public final transient DefaultOutputPort<KeyValPair<K, Short>> sumShort = new DefaultOutputPort<KeyValPair<K, Short>>();
  
  /**
   * Output float sum port.
   */
  @OutputPortFieldAnnotation(name = "sumFloat", optional = true)
  public final transient DefaultOutputPort<KeyValPair<K, Float>> sumFloat = new DefaultOutputPort<KeyValPair<K, Float>>();

  /**
   * Get cumulative flag.
   * @return cumulative flag.
   */
  public boolean isCumulative()
  {
    return cumulative;
  }

  /**
   * 
   * @param cumulative
   */
  public void setCumulative(boolean cumulative)
  {
    this.cumulative = cumulative;
  }


  /**
   * Emits on all ports that are connected. Data is precomputed during process on input port and endWindow just emits it for each key. Clears the internal data.
   */
  @Override
  public void endWindow()
  {
    for (Map.Entry<K, SumEntry> e: sums.entrySet()) {
      K key = e.getKey();
      SumEntry val = e.getValue();
      if (val.changed) {
        sum.emit(new KeyValPair<K, V>(key, getValue(val.sum.doubleValue())));
        sumDouble.emit(new KeyValPair<K, Double>(key, val.sum.doubleValue()));
        sumInteger.emit(new KeyValPair<K, Integer>(key, val.sum.intValue()));
        sumFloat.emit(new KeyValPair<K, Float>(key, val.sum.floatValue()));
        sumShort.emit(new KeyValPair<K, Short>(key, val.sum.shortValue()));
        sumLong.emit(new KeyValPair<K, Long>(key, val.sum.longValue()));
      }
    }
    clearCache();
  }

  /**
   * Clears the cache making this operator stateless on window boundary
   */
  public void clearCache()
  {
    if (cumulative) {
      for (Map.Entry<K, SumEntry> e: sums.entrySet()) {
        SumEntry val = e.getValue();
        val.changed = false;
      }
    }
    else {
      sums.clear();
    }
  }

}
