package org.apache.samoa.topology.impl;

/*
 * #%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.util.LinkedList;
import java.util.List;

import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.samoa.core.ContentEvent;
import org.apache.samoa.topology.AbstractStream;
import org.apache.samoa.topology.IProcessingItem;
import org.apache.samoa.utils.StreamDestination;

/**
 * Stream for multithreaded engine.
 * 
 * @author Anh Thu Vu
 * 
 */
public class ThreadsStream extends AbstractStream {

  private List<StreamDestination> destinations;
  private int counter = 0;
  private int maxCounter = 1;

  public ThreadsStream(IProcessingItem sourcePi) {
    destinations = new LinkedList<StreamDestination>();
  }

  public void addDestination(StreamDestination destination) {
    destinations.add(destination);
    maxCounter *= destination.getParallelism();
  }

  public List<StreamDestination> getDestinations() {
    return this.destinations;
  }

  private int getNextCounter() {
    if (maxCounter > 0 && counter >= maxCounter)
      counter = 0;
    this.counter++;
    return this.counter;
  }

  @Override
  public synchronized void put(ContentEvent event) {
    this.put(event, this.getNextCounter());
  }

  private void put(ContentEvent event, int counter) {
    ThreadsProcessingItem pi;
    int parallelism;
    for (StreamDestination destination : destinations) {
      pi = (ThreadsProcessingItem) destination.getProcessingItem();
      parallelism = destination.getParallelism();
      switch (destination.getPartitioningScheme()) {
      case SHUFFLE:
        pi.processEvent(event, counter % parallelism);
        break;
      case GROUP_BY_KEY:
        pi.processEvent(event, getPIIndexForKey(event.getKey(), parallelism));
        break;
      case BROADCAST:
        for (int p = 0; p < parallelism; p++) {
          pi.processEvent(event, p);
        }
        break;
      }
    }
  }

  private static int getPIIndexForKey(String key, int parallelism) {
    // If key is null, return a default index: 0
    if (key == null)
      return 0;

    // HashCodeBuilder object does not have reset() method
    // So all objects that get appended will be included in the
    // computation of the hashcode.
    // To avoid initialize a HashCodeBuilder for each event,
    // here I use the static method with reflection on the event's key
    int index = HashCodeBuilder.reflectionHashCode(key, true) % parallelism;
    if (index < 0) {
      index += parallelism;
    }
    return index;
  }

}
