/**
 * 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.conf.Configuration;

/**
 * A mapred http server.  
 */
public class StatusHttpServer extends org.apache.hadoop.http.HttpServer {
  /**
   * Create a status server on the given port.
   * The jsp scripts are taken from src/webapps/<name>.
   * @param name The name of the server
   * @param port The port to use on the server
   * @param findPort whether the server should start at the given port and 
   *        increment by 1 until it finds a free port.
   */
  StatusHttpServer(String name, String bindAddress, int port, boolean findPort,
      Configuration conf) throws IOException {
    super(name, bindAddress, port, findPort, conf);
    addServlet("reducegraph", "/taskgraph", TaskGraphServlet.class);
  }

  /** The servlet that outputs svg graphics for map / reduce task 
   *  statuses
   */
  public static 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");

      JobTracker tracker = 
        (JobTracker) getServletContext().getAttribute("job.tracker");
      
      String jobIdStr = request.getParameter("jobid");
      if(jobIdStr == null)
        return;
      JobID jobId = JobID.forName(jobIdStr);
      String typeStr = request.getParameter("type");
      boolean isMap = false;
      if("map".equalsIgnoreCase(typeStr)) {
        isMap = true;
      }
      
      PrintWriter out = response.getWriter();
      TaskReport[] reports = null;
      
      reports = isMap ? tracker.getMapTaskReports(jobId) 
                      : tracker.getReduceTaskReports(jobId);
      
      int numTasks = reports.length;
      if(numTasks <= 0) {
        return;
      }
       
      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
      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
      if(reports != null) {
        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");
    }
  }
  
}

