/**
 * 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.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.mapred.JSPUtil.JobWithViewAccessCheck;
import org.apache.hadoop.security.UserGroupInformation;

/** The servlet that outputs svg graphics for map / reduce task
 *  statuses
 */
@InterfaceAudience.Private
@InterfaceStability.Unstable
public class TaskGraphServlet extends HttpServlet {

  private static final long serialVersionUID = -1365683739392460020L;

  /**height of the graph w/o margins*/ 
  public static final int width = 600;
  
  /**height of the graph w/o margins*/ 
  public static final int height = 200;
  
  /**margin space on y axis */
  public static final int ymargin = 20;

  /**margin space on x axis */
  public static final int xmargin = 80;
  
  private static final float oneThird = 1f / 3f;
  
  @Override
  public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

    response.setContentType("image/svg+xml");

    final JobTracker tracker = 
      (JobTracker) getServletContext().getAttribute("job.tracker");
    
    String jobIdStr = request.getParameter("jobid");
    if(jobIdStr == null)
      return;
    final JobID jobId = JobID.forName(jobIdStr);

    // verify if user has view access for this job
    JobWithViewAccessCheck myJob = JSPUtil.checkAccessAndGetJob(
        tracker, jobId, request, response);
    if (!myJob.isViewJobAllowed()) {
      return;// user is not authorized to view this job
    }

    final boolean isMap = "map".equalsIgnoreCase(request.getParameter("type"));
    final TaskReport[] reports = isMap? tracker.getMapTaskReports(jobId) 
                                      : tracker.getReduceTaskReports(jobId);
    if(reports == null || reports.length == 0) {
      return;
    }

    final int numTasks = reports.length;     
    int tasksPerBar = (int)Math.ceil(numTasks / 600d);
    int numBars = (int) Math.ceil((double)numTasks / tasksPerBar);
    int w = Math.max(600, numBars);
    int barWidth = Math.min(10,  w / numBars); //min 1px, max 10px
    int barsPerNotch = (int)Math.ceil(10d / barWidth);
    w = w + numBars / barsPerNotch;
    int totalWidth = w + 2 * xmargin;
    
    //draw a white rectangle
    final PrintWriter out = response.getWriter();
    out.print("<?xml version=\"1.0\" standalone=\"no\"?>\n" + 
      "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \n" + 
      "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n" +
      "<?xml-stylesheet type=\"text/css\" href=\"/static/hadoop.css\"?>\n\n"+
      "<svg width=\"");out.print(totalWidth);
    out.print("\" height=\"");out.print(height + 2 * ymargin);
    out.print("\" version=\"1.1\"\n" + 
      "xmlns=\"http://www.w3.org/2000/svg\">\n\n"); 
    
    //axes
    printLine(out, xmargin - 1, xmargin - 1, height + ymargin + 1
        , ymargin - 1, "black" );
    printLine(out, xmargin - 1, w + xmargin + 1 ,height + ymargin + 1 
        , height + ymargin + 1, "black" );
    
    //borderlines
    printLine(out, w + xmargin + 1 , w + xmargin +1
        , height + ymargin + 1,ymargin - 1, "#CCCCCC" );
    printLine(out, xmargin - 1, w + xmargin + 1
        , ymargin - 1 , ymargin - 1, "#CCCCCC" );
    
    String[]  colors = new String[] {"#00DD00", "#E50000", "#AAAAFF"};
    
    //determine the notch interval using the number of digits for numTasks
    int xNotchInterval = (int)(Math.ceil( numTasks / 10d));
    
    int xOffset = -1; 
    int xNotchCount = 0;
    //task bar graph
    for(int i=0, barCnt=0; ;i+=tasksPerBar, barCnt++) {
      if(barCnt % barsPerNotch == 0) {
        xOffset++;
      }
      int x = barCnt * barWidth + xmargin + xOffset;
      //x axis notches
      if(i >= xNotchInterval * xNotchCount) {
        printLine(out, x, x, height + ymargin + 3 
            , height + ymargin - 2, "black");
        printText(out, x, height + ymargin + 15 
            , String.valueOf(xNotchInterval * xNotchCount++ ), "middle");
      }
      if(i >= reports.length) break;
      
      if(isMap) {
        float progress = getMapAvarageProgress(tasksPerBar, i, reports);
        int barHeight = (int)Math.ceil(height * progress);
        int y = height - barHeight + ymargin;
        printRect(out, barWidth, barHeight,x , y , colors[2]);
      }
      else {
        float[] progresses 
          = getReduceAvarageProgresses(tasksPerBar, i, reports);
        //draw three bars stacked, for copy, sort, reduce
        
        int prevHeight =0;
        for(int j=0; j < 3 ; j++) {
          int barHeight = (int)((height / 3) * progresses[j]);
          if(barHeight > height/ 3 - 3)//fix rounding error
            barHeight = height / 3 + 1;
          
          int y = height - barHeight + ymargin - prevHeight;
          prevHeight += barHeight;
          printRect(out, barWidth, barHeight, x, y, colors[j] );
        }
      }
    }
    
    //y axis notches
    for(int i=0;i<=10;i++) {
      printLine(out, xmargin-3 , xmargin+2 , ymargin + (i * height) / 10
          , ymargin + (i * height) / 10 , "black");
      printText(out, xmargin - 10 , ymargin + 4 + (i * height) / 10 
          , String.valueOf(100 - i * 10), "end");
    }
    
    if(!isMap) {
      //print color codes for copy, sort, reduce
      printRect(out, 14, 14, xmargin + w + 4, ymargin + 20, colors[0]);
      printText(out, xmargin + w + 24, ymargin + 30, "copy", "start");
      printRect(out, 14, 14, xmargin + w + 4, ymargin + 50, colors[1]);
      printText(out, xmargin + w + 24, ymargin + 60, "sort", "start");
      printRect(out, 14, 14, xmargin + w + 4, ymargin + 80, colors[2]);
      printText(out, xmargin + w + 24, ymargin + 90, "reduce", "start");
    }
    
    
    //firefox curently does not support vertical text
    //out.print("<text x=\"");out.print(6);
    //out.print("\" y=\""); out.print(ymargin + height / 2); 
    //out.print("\" style=\"text-anchor:middle;writing-mode:tb\">"
    //+"Percent</text>\n");
    
    out.print("</svg>");
  }

  /**Computes average progress per bar*/
  private float getMapAvarageProgress(int tasksPerBar, int index
      , TaskReport[] reports ) {
    float progress = 0f;
    int k=0;
    for(;k < tasksPerBar && index + k < reports.length; k++) { 
      progress += reports[index + k].getProgress();
    }
    progress /= k;
    return progress;
  }

  /**Computes average progresses per bar*/
  private float[] getReduceAvarageProgresses(int tasksPerBar, int index
      , TaskReport[] reports ) {
    float[] progresses = new float[] {0,0,0};
    int k=0;
    for(;k < tasksPerBar && index + k < reports.length; k++) {
      float progress = reports[index+k].getProgress();
      for(int j=0; progress > 0 ; j++, progress -= oneThird) {
        if(progress > oneThird)
          progresses[j] += 1f;
        else 
          progresses[j] += progress * 3 ;
      }
    }
    for(int j=0; j<3; j++) { progresses[j] /= k;}
    
    return progresses;
  }
  
  private void printRect(PrintWriter out, int width, int height
      , int x, int y, String color) throws IOException {
    if(height > 0) {
      out.print("<rect width=\"");out.print(width);
      out.print("\" height=\"");  out.print(height);
      out.print("\" x=\""); out.print(x);
      out.print("\" y=\""); out.print(y);
      out.print("\" style=\"fill:"); out.print(color);out.print("\"/>\n");
    }
  }
  private void printLine(PrintWriter out, int x1, int x2
      , int y1, int y2, String color) throws IOException {
    out.print("<line x1=\"");out.print(x1);
    out.print("\" x2=\"");out.print(x2);
    out.print("\" y1=\"");out.print(y1);
    out.print("\" y2=\""); out.print(y2);
    out.print("\" class=\"taskgraphline\" style=\"stroke:"); 
    out.print(color); out.print("\"/>\n"); 
  }
  private void printText(PrintWriter out, int x, int y, String text
      , String anchor) throws IOException {
    out.print("<text x=\"");out.print(String.valueOf(x));
    out.print("\" y=\""); out.print(String.valueOf(y));
    out.print("\" style=\"fill:black;font-family:sans-serif;" 
        + "text-anchor:");out.print(anchor); out.print("\">");
    out.print(text); out.print("</text>\n");
  }
}

