/**
 * 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.hadoop.mapred;

import java.util.Map;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.mapreduce.JobACL;
import org.apache.hadoop.security.authorize.AccessControlList;

/**************************************************
 * Describes the current status of a job.  This is
 * not intended to be a comprehensive piece of data.
 * For that, look at JobProfile.
 *************************************************
 *@deprecated Use {@link org.apache.hadoop.mapreduce.JobStatus} instead
 **/
@Deprecated
@InterfaceAudience.Public
@InterfaceStability.Stable
public class JobStatus extends org.apache.hadoop.mapreduce.JobStatus {

  public static final int RUNNING = 
    org.apache.hadoop.mapreduce.JobStatus.State.RUNNING.getValue();
  public static final int SUCCEEDED = 
    org.apache.hadoop.mapreduce.JobStatus.State.SUCCEEDED.getValue();
  public static final int FAILED = 
    org.apache.hadoop.mapreduce.JobStatus.State.FAILED.getValue();
  public static final int PREP = 
    org.apache.hadoop.mapreduce.JobStatus.State.PREP.getValue();
  public static final int KILLED = 
    org.apache.hadoop.mapreduce.JobStatus.State.KILLED.getValue();

  private static final String UNKNOWN = "UNKNOWN";
  
  private static final String[] runStates =
    {UNKNOWN, "RUNNING", "SUCCEEDED", "FAILED", "PREP", "KILLED"};

  /**
   * Helper method to get human-readable state of the job.
   * @param state job state
   * @return human-readable state of the job
   */
  public static String getJobRunState(int state) {
    if (state < 1 || state >= runStates.length) {
      return UNKNOWN;
    }
    return runStates[state];
  }
  
  static org.apache.hadoop.mapreduce.JobStatus.State getEnum(int state) {
    switch (state) {
      case 1: return org.apache.hadoop.mapreduce.JobStatus.State.RUNNING;
      case 2: return org.apache.hadoop.mapreduce.JobStatus.State.SUCCEEDED;
      case 3: return org.apache.hadoop.mapreduce.JobStatus.State.FAILED;
      case 4: return org.apache.hadoop.mapreduce.JobStatus.State.PREP;
      case 5: return org.apache.hadoop.mapreduce.JobStatus.State.KILLED;
    }
    return null;
  }
  
  /**
   */
  public JobStatus() {
  }

  /**
   * Create a job status object for a given jobid.
   * @param jobid The jobid of the job
   * @param mapProgress The progress made on the maps
   * @param reduceProgress The progress made on the reduces
   * @param cleanupProgress The progress made on cleanup
   * @param runState The current state of the job
   * @param user userid of the person who submitted the job.
   * @param jobName user-specified job name.
   * @param jobFile job configuration file. 
   * @param trackingUrl link to the web-ui for details of the job.
   */
  public JobStatus(JobID jobid, float mapProgress, float reduceProgress,
                   float cleanupProgress, int runState, 
                   String user, String jobName, 
                   String jobFile, String trackingUrl) {
    this(jobid, mapProgress, reduceProgress, cleanupProgress, runState,
                  JobPriority.NORMAL, user, jobName, jobFile, trackingUrl);
  }

  /**
   * Create a job status object for a given jobid.
   * @param jobid The jobid of the job
   * @param mapProgress The progress made on the maps
   * @param reduceProgress The progress made on the reduces
   * @param runState The current state of the job
   * @param user userid of the person who submitted the job.
   * @param jobName user-specified job name.
   * @param jobFile job configuration file. 
   * @param trackingUrl link to the web-ui for details of the job.
   */
  public JobStatus(JobID jobid, float mapProgress, float reduceProgress,
                   int runState, String user, String jobName, 
                   String jobFile, String trackingUrl) {
    this(jobid, mapProgress, reduceProgress, 0.0f, runState, user, jobName, 
        jobFile, trackingUrl);
  }

  /**
   * Create a job status object for a given jobid.
   * @param jobid The jobid of the job
   * @param mapProgress The progress made on the maps
   * @param reduceProgress The progress made on the reduces
   * @param runState The current state of the job
   * @param jp Priority of the job.
   * @param user userid of the person who submitted the job.
   * @param jobName user-specified job name.
   * @param jobFile job configuration file. 
   * @param trackingUrl link to the web-ui for details of the job.
   */
   public JobStatus(JobID jobid, float mapProgress, float reduceProgress,
                      float cleanupProgress, int runState, JobPriority jp, 
                      String user, String jobName, String jobFile, 
                      String trackingUrl) {
     this(jobid, 0.0f, mapProgress, reduceProgress, 
          cleanupProgress, runState, jp, user, jobName, jobFile, trackingUrl);
   }
   
  /**
   * Create a job status object for a given jobid.
   * @param jobid The jobid of the job
   * @param setupProgress The progress made on the setup
   * @param mapProgress The progress made on the maps
   * @param reduceProgress The progress made on the reduces
   * @param cleanupProgress The progress made on the cleanup
   * @param runState The current state of the job
   * @param jp Priority of the job.
   * @param user userid of the person who submitted the job.
   * @param jobName user-specified job name.
   * @param jobFile job configuration file. 
   * @param trackingUrl link to the web-ui for details of the job.
   */
   public JobStatus(JobID jobid, float setupProgress, float mapProgress,
                    float reduceProgress, float cleanupProgress, 
                    int runState, JobPriority jp, String user, String jobName, 
                    String jobFile, String trackingUrl) {
     super(jobid, setupProgress, mapProgress, reduceProgress, cleanupProgress,
       getEnum(runState), org.apache.hadoop.mapreduce.JobPriority.valueOf(jp.name()),
       user, jobName, jobFile, trackingUrl);
   }
   
  public static JobStatus downgrade(org.apache.hadoop.mapreduce.JobStatus stat){
    JobStatus old = new JobStatus(JobID.downgrade(stat.getJobID()),
      stat.getSetupProgress(), stat.getMapProgress(), stat.getReduceProgress(),
      stat.getCleanupProgress(), stat.getState().getValue(), 
      JobPriority.valueOf(stat.getPriority().name()),
      stat.getUsername(), stat.getJobName(), stat.getJobFile(),
      stat.getTrackingUrl());
    old.setStartTime(stat.getStartTime());
    old.setFinishTime(stat.getFinishTime());
    old.setSchedulingInfo(stat.getSchedulingInfo());
    old.setHistoryFile(stat.getHistoryFile());
    return old;
  }
  /**
   * @deprecated use getJobID instead
   */
  @Deprecated
  public String getJobId() { return getJobID().toString(); }
  
  /**
   * @return The jobid of the Job
   */
  public JobID getJobID() { return JobID.downgrade(super.getJobID()); }
  
  /**
   * Return the priority of the job
   * @return job priority
   */
   public synchronized JobPriority getJobPriority() { 
     return JobPriority.valueOf(super.getPriority().name());
   }

   /**
    * Sets the map progress of this job
    * @param p The value of map progress to set to
    */
   protected synchronized void setMapProgress(float p) { 
     super.setMapProgress(p); 
   }

   /**
    * Sets the cleanup progress of this job
    * @param p The value of cleanup progress to set to
    */
   protected synchronized void setCleanupProgress(float p) { 
     super.setCleanupProgress(p); 
   }

   /**
    * Sets the setup progress of this job
    * @param p The value of setup progress to set to
    */
   protected synchronized void setSetupProgress(float p) { 
     super.setSetupProgress(p); 
   }

   /**
    * Sets the reduce progress of this Job
    * @param p The value of reduce progress to set to
    */
   protected synchronized void setReduceProgress(float p) { 
     super.setReduceProgress(p); 
   }
     
   /** 
    * Set the finish time of the job
    * @param finishTime The finishTime of the job
    */
   protected synchronized void setFinishTime(long finishTime) {
     super.setFinishTime(finishTime);
   }

   /**
    * Set the job history file url for a completed job
    */
   protected synchronized void setHistoryFile(String historyFile) {
     super.setHistoryFile(historyFile);
   }

   /**
    * Set the link to the web-ui for details of the job.
    */
   protected synchronized void setTrackingUrl(String trackingUrl) {
     super.setTrackingUrl(trackingUrl);
   }

   /**
    * Set the job retire flag to true.
    */
   protected synchronized void setRetired() {
     super.setRetired();
   }

   /**
    * Change the current run state of the job.
    */
   protected synchronized void setRunState(int state) {
     super.setState(getEnum(state));
   }

   /**
    * @return running state of the job
    */
   public synchronized int getRunState() { return super.getState().getValue(); }
     

   /** 
    * Set the start time of the job
    * @param startTime The startTime of the job
    */
   protected synchronized void setStartTime(long startTime) { 
     super.setStartTime(startTime);
   }
     
   /**
    * @param userName The username of the job
    */
   protected synchronized void setUsername(String userName) { 
     super.setUsername(userName);
   }

   /**
    * Used to set the scheduling information associated to a particular Job.
    * 
    * @param schedulingInfo Scheduling information of the job
    */
   protected synchronized void setSchedulingInfo(String schedulingInfo) {
     super.setSchedulingInfo(schedulingInfo);
   }

   protected synchronized void setJobACLs(Map<JobACL, AccessControlList> acls) {
     super.setJobACLs(acls);
   }

  /**
   * Set the priority of the job, defaulting to NORMAL.
   * @param jp new job priority
   */
   public synchronized void setJobPriority(JobPriority jp) {
     super.setPriority(
       org.apache.hadoop.mapreduce.JobPriority.valueOf(jp.name()));
   }
  
   /**
    * @return Percentage of progress in maps 
    */
   public synchronized float mapProgress() { return super.getMapProgress(); }
     
   /**
    * @return Percentage of progress in cleanup 
    */
   public synchronized float cleanupProgress() { 
     return super.getCleanupProgress(); 
   }
     
   /**
    * @return Percentage of progress in setup 
    */
   public synchronized float setupProgress() { 
     return super.getSetupProgress(); 
   }
     
   /**
    * @return Percentage of progress in reduce 
    */
   public synchronized float reduceProgress() { 
     return super.getReduceProgress(); 
   }

   // A utility to convert new job runstates to the old ones.
   static int getOldNewJobRunState(
     org.apache.hadoop.mapreduce.JobStatus.State state) {
     return state.getValue();
   }
}