package ch.epfl.data.squall.storm_components.hyper_cube.stream_grouping;

import backtype.storm.generated.GlobalStreamId;
import backtype.storm.grouping.CustomStreamGrouping;
import backtype.storm.task.WorkerTopologyContext;
import ch.epfl.data.squall.thetajoin.matrix_assignment.HyperCubeAssignment;
import ch.epfl.data.squall.utilities.MyUtilities;
import org.apache.log4j.Logger;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by khayyam on 4/10/15.
 */
public class HyperCubeGrouping implements CustomStreamGrouping {
    private static final long serialVersionUID = 1L;
    private static Logger LOG = Logger.getLogger(HyperCubeGrouping.class);

    private final HyperCubeAssignment _assignment;
    private final String[] _emitterIndexes;
    private List<Integer> _targetTasks;
    private final Map _map;

    public HyperCubeGrouping(String[] emitterIndexes,
                             HyperCubeAssignment assignment, Map map) {
        _assignment = assignment;
        _emitterIndexes = emitterIndexes;
        _map = map;
    }

    // @Override
    @Override
    public List<Integer> chooseTasks(int taskId, List<Object> stormTuple) {
        // the following is checking for FinalAck
        if (!MyUtilities.isManualBatchingMode(_map)) {
            final List<String> tuple = (List<String>) stormTuple.get(1); // TUPLE
            if (MyUtilities.isFinalAck(tuple, _map))
                return _targetTasks;
        } else {
            final String tupleBatch = (String) stormTuple.get(1); // TUPLE
            if (MyUtilities.isFinalAckManualBatching(tupleBatch, _map))
                // send to everyone
                return _targetTasks;
        }

        // the following picks tasks for Non-FinalAck
        return chooseTasksNonFinalAck(stormTuple);
    }

    private List<Integer> chooseTasksNonFinalAck(List<Object> stormTuple) {
        // ////////////////
        List<Integer> tasks = null;
        final String tableName = (String) stormTuple.get(0);
        for (int i = 0; i < _emitterIndexes.length; i++)
            if (tableName.equals(_emitterIndexes[i])) {
                List<Integer> regionsID = _assignment.getRegionIDs(HyperCubeAssignment.Dimension.d(i));
                tasks = translateIdsToTasks(regionsID);
                break;
            }


        if (tasks == null) {
            for (int i = 0; i < _emitterIndexes.length; i++)
                LOG.info("First Name: " + _emitterIndexes[i]);

            LOG.info("Table Name: " + tableName);
            LOG.info("WRONG ASSIGNMENT");
        }
        return tasks;
    }

    @Override
    public void prepare(WorkerTopologyContext wtc, GlobalStreamId gsi,
                        List<Integer> targetTasks) {
        // LOG.info("Number of tasks is : "+numTasks);
        _targetTasks = targetTasks;
    }

    private List<Integer> translateIdsToTasks(List<Integer> ids) {

        for (int i = 0; i < _targetTasks.size(); i++)
            System.out.println(_targetTasks.get(i));

        final List<Integer> converted = new ArrayList<Integer>();
        for (final int id : ids)
            converted.add(_targetTasks.get(id));
        return converted;
    }

}

@@ -2764,63 +2764,8 @@
 ) %7B%0A
-        // LOG.info(%22Number of tasks is : %22+numTasks);%0A
     
@@ -2875,116 +2875,8 @@
  %7B%0A%0A
-        for (int i = 0; i %3C _targetTasks.size(); i++)%0A            System.out.println(_targetTasks.get(i));%0A%0A
     

remove println