/**
 * 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.tez.runtime.library.common.shuffle.impl;

import java.net.URI;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tez.dag.api.TezUncheckedException;
import org.apache.tez.runtime.api.Event;
import org.apache.tez.runtime.api.TezInputContext;
import org.apache.tez.runtime.api.events.DataMovementEvent;
import org.apache.tez.runtime.api.events.InputFailedEvent;
import org.apache.tez.runtime.api.events.InputInformationEvent;
import org.apache.tez.runtime.library.common.InputAttemptIdentifier;
import org.apache.tez.runtime.library.shuffle.impl.ShuffleUserPayloads.DataMovementEventPayloadProto;
import org.apache.tez.runtime.library.shuffle.impl.ShuffleUserPayloads.InputInformationEventPayloadProto;

import com.google.common.base.Preconditions;
import com.google.protobuf.InvalidProtocolBufferException;

public class ShuffleInputEventHandler {
  
  private static final Log LOG = LogFactory.getLog(ShuffleInputEventHandler.class);

  private final ShuffleScheduler scheduler;
  private final TezInputContext inputContext;
  private final Shuffle shuffle;

  private int maxMapRuntime = 0;
  private boolean shuffleRangeSet = false;
  
  public ShuffleInputEventHandler(TezInputContext inputContext,
      Shuffle shuffle, ShuffleScheduler scheduler) {
    this.inputContext = inputContext;
    this.shuffle = shuffle;
    this.scheduler = scheduler;
  }

  public void handleEvents(List<Event> events) {
    for (Event event : events) {
      handleEvent(event);
    }
  }
  
  
  private void handleEvent(Event event) {
    if (event instanceof InputInformationEvent) {
      processInputInformationEvent((InputInformationEvent) event);
    }
    else if (event instanceof DataMovementEvent) {
      processDataMovementEvent((DataMovementEvent) event);      
    } else if (event instanceof InputFailedEvent) {
      processTaskFailedEvent((InputFailedEvent) event);
    }
  }

  private void processInputInformationEvent(InputInformationEvent iiEvent) {
    InputInformationEventPayloadProto inputInfoPayload;
    try {
      inputInfoPayload = InputInformationEventPayloadProto.parseFrom(iiEvent.getUserPayload());
    } catch (InvalidProtocolBufferException e) {
      throw new TezUncheckedException("Unable to parse InputInformationEvent payload", e);
    }
    int partitionRange = inputInfoPayload.getPartitionRange();
    shuffle.setPartitionRange(partitionRange);
    this.shuffleRangeSet = true;
  }

  private void processDataMovementEvent(DataMovementEvent dmEvent) {
    // FIXME TODO NEWTEZ
    // Preconditions.checkState(shuffleRangeSet == true, "Shuffle Range must be set before a DataMovementEvent is processed");
    DataMovementEventPayloadProto shufflePayload;
    try {
      shufflePayload = DataMovementEventPayloadProto.parseFrom(dmEvent.getUserPayload());
    } catch (InvalidProtocolBufferException e) {
      throw new TezUncheckedException("Unable to parse DataMovementEvent payload", e);
    } 
    int partitionId = dmEvent.getSourceIndex();
    URI baseUri = getBaseURI(shufflePayload.getHost(), shufflePayload.getPort(), partitionId);

    InputAttemptIdentifier srcAttemptIdentifier = new InputAttemptIdentifier(dmEvent.getTargetIndex(), dmEvent.getVersion(), shufflePayload.getPathComponent());
    scheduler.addKnownMapOutput(shufflePayload.getHost(), partitionId, baseUri.toString(), srcAttemptIdentifier);
    
    // TODO NEWTEZ See if this duration hack can be removed.
    int duration = shufflePayload.getRunDuration();
    if (duration > maxMapRuntime) {
      maxMapRuntime = duration;
      scheduler.informMaxMapRunTime(maxMapRuntime);
    }
  }
  
  private void processTaskFailedEvent(InputFailedEvent ifEvent) {
    InputAttemptIdentifier taIdentifier = new InputAttemptIdentifier(ifEvent.getSourceIndex(), ifEvent.getVersion());
    scheduler.obsoleteMapOutput(taIdentifier);
    LOG.info("Obsoleting output of src-task: " + taIdentifier);
  }

  // TODO NEWTEZ Handle encrypted shuffle
  private URI getBaseURI(String host, int port, int partitionId) {
    StringBuilder sb = new StringBuilder("http://");
    sb.append(host);
    sb.append(":");
    sb.append(String.valueOf(port));
    sb.append("/");
    
    sb.append("mapOutput?job=");
    // Required to use the existing ShuffleHandler
    sb.append(inputContext.getApplicationId().toString().replace("application", "job"));
    
    sb.append("&reduce=");
    sb.append(partitionId);
    sb.append("&map=");
    URI u = URI.create(sb.toString());
    return u;
  }
}
