/*
 * 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 org.apache.samoa.topology.impl;

import java.util.Arrays;
import java.util.Collection;

import mockit.Expectations;
import mockit.Mocked;
import mockit.NonStrictExpectations;
import mockit.Tested;

import org.apache.samoa.core.ContentEvent;
import org.apache.samoa.topology.impl.SimpleProcessingItem;
import org.apache.samoa.topology.impl.SimpleStream;
import org.apache.samoa.utils.PartitioningScheme;
import org.apache.samoa.utils.StreamDestination;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/**
 * @author Anh Thu Vu
 * 
 */
@RunWith(Parameterized.class)
public class SimpleStreamTest {

  @Tested
  private SimpleStream stream;

  @Mocked
  private SimpleProcessingItem sourcePi, destPi;
  @Mocked
  private ContentEvent event;
  @Mocked
  private StreamDestination destination;

  private final String eventKey = "eventkey";
  private final int parallelism;
  private final PartitioningScheme scheme;

  @Parameters
  public static Collection<Object[]> generateParameters() {
    return Arrays.asList(new Object[][] {
        { 2, PartitioningScheme.SHUFFLE },
        { 3, PartitioningScheme.GROUP_BY_KEY },
        { 4, PartitioningScheme.BROADCAST }
    });
  }

  public SimpleStreamTest(int parallelism, PartitioningScheme scheme) {
    this.parallelism = parallelism;
    this.scheme = scheme;
  }

  @Before
  public void setUp() throws Exception {
    stream = new SimpleStream(sourcePi);
    stream.addDestination(destination);
  }

  @Test
  public void testPut() {
    new NonStrictExpectations() {
      {
        event.getKey();
        result = eventKey;
        destination.getProcessingItem();
        result = destPi;
        destination.getPartitioningScheme();
        result = scheme;
        destination.getParallelism();
        result = parallelism;

      }
    };
    switch (this.scheme) {
    case SHUFFLE:
    case GROUP_BY_KEY:
      new Expectations() {
        {
          // TODO: restrict the range of counter value
          destPi.processEvent(event, anyInt);
          times = 1;
        }
      };
      break;
    case BROADCAST:
      new Expectations() {
        {
          // TODO: restrict the range of counter value
          destPi.processEvent(event, anyInt);
          times = parallelism;
        }
      };
      break;
    }
    stream.put(event);
  }

}
