/*
 * 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.
 */

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.apache.samoa.topology.impl;

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;

/**
 * 
 * @author abifet
 */
class SimpleStream extends AbstractStream {
  private List<StreamDestination> destinations;
  private int maxCounter;
  private int eventCounter;

  SimpleStream(IProcessingItem sourcePi) {
    super(sourcePi);
    this.destinations = new LinkedList<>();
    this.eventCounter = 0;
    this.maxCounter = 1;
  }

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

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

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

  public void addDestination(StreamDestination destination) {
    this.destinations.add(destination);
    if (maxCounter <= 0)
      maxCounter = 1;
    maxCounter *= destination.getParallelism();
  }
}
