/*
 * Copyright 2010 Google Inc.
 *
 * Licensed 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.
 */

/********* Common functions *********/

// Sets the status butter, optionally indicating if it's an error message.
function setButter(message, error) {
  var butter = getButterBar();
  // Prevent flicker on butter update by hiding it first.
  butter.hide();
  if (error) {
    butter.removeClass('info').addClass('error').text(message);
  } else {
    butter.removeClass('error').addClass('info').text(message);
  }
  butter.show();
  $(document).scrollTop(0);
}

// Hides the butter bar.
function hideButter() {
  getButterBar().hide();
}

// Fetches the butter bar dom element.
function getButterBar() {
  return $('#butter');
}


// Renders a value with a collapsable twisty.
function renderCollapsableValue(value, container) {
  var stringValue = $.toJSON(value);
  var SPLIT_LENGTH = 200;
  if (stringValue.length < SPLIT_LENGTH) {
    container.append($('<span>').text(stringValue));
    return;
  }

  var startValue = stringValue.substr(0, SPLIT_LENGTH);
  var endValue = stringValue.substr(SPLIT_LENGTH);

  // Split the end value with <wbr> tags so it looks nice; forced
  // word wrapping never works right.
  var moreSpan = $('<span class="value-disclosure-more">');
  moreSpan.hide();
  for (var i = 0; i < endValue.length; i += SPLIT_LENGTH) {
    moreSpan.append(endValue.substr(i, SPLIT_LENGTH));
    moreSpan.append('<wbr/>');
  }
  var betweenMoreText = '...(' + endValue.length + ' more) ';
  var betweenSpan = $('<span class="value-disclosure-between">')
      .text(betweenMoreText);
  var toggle = $('<a class="value-disclosure-toggle">')
      .text('Expand')
      .attr('href', '');
  toggle.click(function(e) {
      e.preventDefault();
      if (moreSpan.is(':hidden')) {
        betweenSpan.text(' ');
        toggle.text('Collapse');
      } else {
        betweenSpan.text(betweenMoreText);
        toggle.text('Expand');
      }
      moreSpan.toggle();
  });
  container.append($('<span>').text(startValue));
  container.append(moreSpan);
  container.append(betweenSpan);
  container.append(toggle);
}

// Given an AJAX error message (which is empty or null on success) and a
// data payload containing JSON, parses the data payload and returns the object.
// Server-side errors and AJAX errors will be brought to the user's attention
// if present in the response object
function getResponseDataJson(error, data) {
  var response = null;
  try {
    response = $.parseJSON(data);
  } catch (e) {
    error = '' + e;
  }
  if (response && response.error_class) {
    error = response.error_class + ': ' + response.error_message;
  } else if (!response) {
    error = 'Could not parse response JSON data.';
  }
  if (error) {
    setButter(error, true);
    return null;
  }
  return response;
}

// Retrieve the list of configs.
function listConfigs(resultFunc) {
  $.ajax({
    type: 'GET',
    url: 'command/list_configs',
    dataType: 'text',
    error: function(request, textStatus) {
      getResponseDataJson(textStatus);
    },
    success: function(data, textStatus, request) {
      var response = getResponseDataJson(null, data);
      if (response) {
        resultFunc(response.configs);
      }
    }
  });
}

// Return the list of job records and notifies the user the content
// is being fetched.
function listJobs(cursor, resultFunc) {
  // If the user is paging then they scrolled down so let's
  // help them by scrolling the window back to the top.
  var jumpToTop = !!cursor;
  cursor = cursor ? cursor : '';
  setButter('Loading');
  $.ajax({
    type: 'GET',
    url: 'command/list_jobs?cursor=' + cursor,
    dataType: 'text',
    error: function(request, textStatus) {
      getResponseDataJson(textStatus);
    },
    success: function(data, textStatus, request) {
      var response = getResponseDataJson(null, data);
      if (response) {
        resultFunc(response.jobs, response.cursor);
        if (jumpToTop) {
          window.scrollTo(0, 0);
        }
        hideButter();  // Hide the loading message.
      }
    }
  });
}

// Cleans up a job with the given name and ID, updates butter with status.
function cleanUpJob(name, mapreduce_id) {
  if (!confirm('Clean up job "' + name +
               '" with ID "' + mapreduce_id + '"?')) {
    return;
  }

  $.ajax({
    async: false,
    type: 'POST',
    url: 'command/cleanup_job',
    data: {'mapreduce_id': mapreduce_id},
    dataType: 'text',
    error: function(request, textStatus) {
      getResponseDataJson(textStatus);
    },
    success: function(data, textStatus, request) {
      var response = getResponseDataJson(null, data);
      if (response) {
        setButter(response.status);
        if (!response.status.error) {
          $('#row-' + mapreduce_id).remove();
        }
      }
    }
  });
}

// Aborts the job with the given ID, updates butter with status.
function abortJob(name, mapreduce_id) {
  if (!confirm('Abort job "' + name + '" with ID "' + mapreduce_id + '"?')) {
    return;
  }

  $.ajax({
    async: false,
    type: 'POST',
    url: 'command/abort_job',
    data: {'mapreduce_id': mapreduce_id},
    dataType: 'text',
    error: function(request, textStatus) {
      getResponseDataJson(textStatus);
    },
    success: function(data, textStatus, request) {
      var response = getResponseDataJson(null, data);
      if (response) {
        setButter(response.status);
      }
    }
  });
}

// Retrieve the detail for a job.
function getJobDetail(jobId, resultFunc) {
  $.ajax({
    type: 'GET',
    url: 'command/get_job_detail',
    dataType: 'text',
    data: {'mapreduce_id': jobId},
    statusCode: {
      404: function() {
        setButter('job ' + jobId + ' was not found.', true);
      }
    },
    error: function(request, textStatus) {
      getResponseDataJson(textStatus);
    },
    success: function(data, textStatus, request) {
      var response = getResponseDataJson(null, data);
      if (response) {
        resultFunc(jobId, response);
      }
    }
  });
}

// Turns a key into a nicely scrubbed parameter name.
function getNiceParamKey(key) {
  // TODO: Figure out if we want to do this at all.
  return key;
}

// Returns an array of the keys of an object in sorted order.
function getSortedKeys(obj) {
  var keys = [];
  $.each(obj, function(key, value) {
    keys.push(key);
  });
  keys.sort();
  return keys;
}

// Convert milliseconds since the epoch to an ISO8601 datestring.
// Consider using new Date().toISOString() instead (J.S 1.8+)
function getIso8601String(timestamp_ms) {
  var time = new Date();
  time.setTime(timestamp_ms);
  return '' +
      time.getUTCFullYear() + '-' +
      leftPadNumber(time.getUTCMonth() + 1, 2, '0') + '-' +
      leftPadNumber(time.getUTCDate(), 2, '0') + 'T' +
      leftPadNumber(time.getUTCHours(), 2, '0') + ':' +
      leftPadNumber(time.getUTCMinutes(), 2, '0') + ':' +
      leftPadNumber(time.getUTCSeconds(), 2, '0') + 'Z';
}

function leftPadNumber(number, minSize, paddingChar) {
  var stringified = '' + number;
  if (stringified.length < minSize) {
    for (var i = 0; i < (minSize - stringified.length); ++i) {
      stringified = paddingChar + stringified;
    }
  }
  return stringified;
}

// Get locale time string for time portion of job runtime. Specially
// handle number of days running as a prefix.
function getElapsedTimeString(start_timestamp_ms, updated_timestamp_ms) {
  var updatedDiff = updated_timestamp_ms - start_timestamp_ms;
  var updatedDays = Math.floor(updatedDiff / 86400000.0);
  updatedDiff -= (updatedDays * 86400000.0);
  var updatedHours = Math.floor(updatedDiff / 3600000.0);
  updatedDiff -= (updatedHours * 3600000.0);
  var updatedMinutes = Math.floor(updatedDiff / 60000.0);
  updatedDiff -= (updatedMinutes * 60000.0);
  var updatedSeconds = Math.floor(updatedDiff / 1000.0);

  var updatedString = '';
  if (updatedDays == 1) {
    updatedString = '1 day, ';
  } else if (updatedDays > 1) {
    updatedString = '' + updatedDays + ' days, ';
  }
  updatedString +=
      leftPadNumber(updatedHours, 2, '0') + ':' +
      leftPadNumber(updatedMinutes, 2, '0') + ':' +
      leftPadNumber(updatedSeconds, 2, '0');

  return updatedString;
}

// Retrieves the mapreduce_id from the query string.
function getJobId() {
  var jobId = $.url().param('mapreduce_id');
  return jobId == null ? '' : jobId;
}

/********* Specific to overview status page *********/

//////// Running jobs overview.
function initJobOverview(jobs, cursor) {
  // Empty body.
  var body = $('#running-list > tbody');
  body.empty();

  if (!jobs || (jobs && jobs.length == 0)) {
    $('<td colspan="8">').text('No job records found.').appendTo(body);
    return;
  }

  // Show header.
  $('#running-list > thead').show();

  // Populate the table.
  $.each(jobs, function(index, job) {
    var row = $('<tr id="row-' + job.mapreduce_id + '">');

    var status = (job.active ? 'running' : job.result_status) || 'unknown';
    row.append($('<td class="status-text">').text(status));

    $('<td>').append(
      $('<a>')
        .attr('href', 'detail?mapreduce_id=' + job.mapreduce_id)
        .text('Detail')).appendTo(row);

    row.append($('<td>').text(job.mapreduce_id))
      .append($('<td>').text(job.name));

    var activity = '' + job.active_shards + ' / ' + job.shards + ' shards';
    row.append($('<td>').text(activity))

    row.append($('<td>').text(getIso8601String(job.start_timestamp_ms)));

    row.append($('<td>').text(getElapsedTimeString(
        job.start_timestamp_ms, job.updated_timestamp_ms)));

    // Controller links for abort, cleanup, etc.
    if (job.active) {
      var control = $('<a href="">').text('Abort')
        .click(function(event) {
          abortJob(job.name, job.mapreduce_id);
          event.stopPropagation();
          return false;
        });
      row.append($('<td>').append(control));
    } else {
      var control = $('<a href="">').text('Cleanup')
        .click(function(event) {
          cleanUpJob(job.name, job.mapreduce_id);
          event.stopPropagation();
          return false;
        });
      row.append($('<td>').append(control));
    }
    row.appendTo(body);
  });

  // Set up the next/first page links.
  $('#running-first-page')
    .show()
    .unbind('click')
    .click(function() {
    listJobs(null, initJobOverview);
    return false;
  });
  $('#running-next-page').unbind('click');
  if (cursor) {
    $('#running-next-page')
      .show()
      .click(function() {
        listJobs(cursor, initJobOverview);
        return false;
      });
  } else {
    $('#running-next-page').hide();
  }
  $('#running-list > tfoot').show();
}

//////// Launching jobs.

// TODO(aizatsky): new job parameters shouldn't be hidden by default.
var FIXED_JOB_PARAMS = [
    'name', 'mapper_input_reader', 'mapper_handler', 'mapper_params_validator',
    'mapper_output_writer'
];

var EDITABLE_JOB_PARAMS = ['shard_count', 'processing_rate', 'queue_name'];

function getJobForm(name) {
  return $('form.run-job > input[name="name"][value="' + name + '"]').parent();
}

function showRunJobConfig(name) {
  var matchedForm = null;
  $.each($('form.run-job'), function(index, jobForm) {
    if ($(jobForm).find('input[name="name"]').val() == name) {
      matchedForm = jobForm;
    } else {
      $(jobForm).hide();
    }
  });
  $(matchedForm).show();
}

function runJobDone(name, error, data) {
  var jobForm = getJobForm(name);
  var response = getResponseDataJson(error, data);
  if (response) {
    setButter('Successfully started job "' + response['mapreduce_id'] + '"');
    listJobs(null, initJobOverview);
  }
  jobForm.find('input[type="submit"]').attr('disabled', null);
}

function runJob(name) {
  var jobForm = getJobForm(name);
  jobForm.find('input[type="submit"]').attr('disabled', 'disabled');
  $.ajax({
    type: 'POST',
    url: 'command/start_job',
    data: jobForm.serialize(),
    dataType: 'text',
    error: function(request, textStatus) {
      runJobDone(name, textStatus);
    },
    success: function(data, textStatus, request) {
      runJobDone(name, null, data);
    }
  });
}

function initJobLaunching(configs) {
  $('#launch-control').empty();
  if (!configs || (configs && configs.length == 0)) {
    $('#launch-control').append('No job configurations found.');
    return;
  }

  // Set up job config forms.
  $.each(configs, function(index, config) {
    var jobForm = $('<form class="run-job">')
      .submit(function() {
        runJob(config.name);
        return false;
      })
      .hide()
      .appendTo('#launch-container');

    // Fixed job config values.
    $.each(FIXED_JOB_PARAMS, function(unused, key) {
      var value = config[key];
      if (!value) return;
      if (key != 'name') {
        // Name is up in the page title so doesn't need to be shown again.
        $('<p class="job-static-param">')
          .append($('<span class="param-key">').text(getNiceParamKey(key)))
          .append($('<span>').text(': '))
          .append($('<span class="param-value">').text(value))
          .appendTo(jobForm);
      }
      $('<input type="hidden">')
        .attr('name', key)
        .attr('value', value)
        .appendTo(jobForm);
    });

    // Add parameter values to the job form.
    function addParameters(params, prefix) {
      if (!params) {
        return;
      }

      var sortedParams = getSortedKeys(params);
      $.each(sortedParams, function(index, key) {
        var value = params[key];
        var paramId = 'job-' + prefix + key + '-param';
        var paramP = $('<p class="editable-input">');

        // Deal with the case in which the value is an object rather than
        // just the default value string.
        var prettyKey = key;
        if (value && value['human_name']) {
          prettyKey = value['human_name'];
        }

        if (value && value['default_value']) {
          value = value['default_value'];
        }

        $('<label>')
          .attr('for', paramId)
          .text(prettyKey)
          .appendTo(paramP);
        $('<span>').text(': ').appendTo(paramP);
        $('<input type="text">')
          .attr('id', paramId)
          .attr('name', prefix + key)
          .attr('value', value)
          .appendTo(paramP);
        paramP.appendTo(jobForm);
      });
    }

    addParameters(config.params, 'params.');
    addParameters(config.mapper_params, 'mapper_params.');

    $('<input type="submit">')
      .attr('value', 'Run')
      .appendTo(jobForm);
  });

  // Setup job name drop-down.
  var jobSelector = $('<select>')
      .change(function(event) {
        showRunJobConfig($(event.target).val());
      })
      .appendTo('#launch-control');
  $.each(configs, function(index, config) {
    $('<option>')
      .attr('name', config.name)
      .text(config.name)
      .appendTo(jobSelector);
  });
  showRunJobConfig(jobSelector.val());
}

//////// Status page entry point.
function initStatus() {
  listConfigs(initJobLaunching);
  listJobs(null, initJobOverview);
}

/********* Specific to detail status page *********/

//////// Job detail.
function refreshJobDetail(jobId, detail) {
  // Overview parameters.
  var jobParams = $('#detail-params');
  jobParams.empty();

  var status = (detail.active ? 'running' : detail.result_status) || 'unknown';
  $('<li class="status-text">').text(status).appendTo(jobParams);

  $('<li>')
    .append($('<span class="param-key">').text('Elapsed time'))
    .append($('<span>').text(': '))
    .append($('<span class="param-value">').text(getElapsedTimeString(
          detail.start_timestamp_ms, detail.updated_timestamp_ms)))
    .appendTo(jobParams);
  $('<li>')
    .append($('<span class="param-key">').text('Start time'))
    .append($('<span>').text(': '))
    .append($('<span class="param-value">').text(getIso8601String(
          detail.start_timestamp_ms)))
    .appendTo(jobParams);

  $.each(FIXED_JOB_PARAMS, function(index, key) {
    // Skip some parameters or those with no values.
    if (key == 'name') return;
    var value = detail[key];
    if (!value) return;

    $('<li>')
      .append($('<span class="param-key">').text(getNiceParamKey(key)))
      .append($('<span>').text(': '))
      .append($('<span class="param-value">').text('' + value))
      .appendTo(jobParams);
  });

  // User-supplied parameters.
  if (detail.mapper_spec.mapper_params) {
    var sortedKeys = getSortedKeys(detail.mapper_spec.mapper_params);
    $.each(sortedKeys, function(index, key) {
      var value = detail.mapper_spec.mapper_params[key];
      var valueSpan = $('<span class="param-value">');
      renderCollapsableValue(value, valueSpan);
      $('<li>')
        .append($('<span class="user-param-key">').text(key))
        .append($('<span>').text(': '))
        .append(valueSpan)
        .appendTo(jobParams);
    });
  }

  // Graph image.
  var detailGraph = $('#detail-graph');
  detailGraph.empty();
  var chartTitle = 'Processed items per shard';
  if (detail.chart_data) {
    var data = new google.visualization.DataTable();
    data.addColumn('string', 'Shard');
    data.addColumn('number', 'Count');
    var shards = detail.chart_data.length;
    for (var i = 0; i < shards; i++) {
      data.addRow([i.toString(), detail.chart_data[i]]);
    }
    var log2Shards = Math.log(shards) / Math.log(2);
    var chartWidth = Math.max(Math.max(300, shards * 2), 100 * log2Shards);
    var chartHeight = 200;
    var options = {
        legend: 'none',
        bar: {
            groupWidth: '100%'
        },
        vAxis: {
          minValue: 0
        },
        title: chartTitle,
        chartArea: {
          width: chartWidth,
          height: chartHeight
        },
        width: 80 + chartWidth,
        height: 80 + chartHeight
    };
    var chart = new google.visualization.ColumnChart(detailGraph[0]);
    chart.draw(data, options);
  } else {
    $('<div>').text(chartTitle).appendTo(detailGraph);
    $('<img>')
      .attr('src', detail.chart_url)
      .attr('width', detail.chart_width || 300)
      .attr('height', 200)
      .appendTo(detailGraph);
  }

  // Aggregated counters.
  var aggregatedCounters = $('#aggregated-counters');
  aggregatedCounters.empty();
  var runtimeMs = detail.updated_timestamp_ms - detail.start_timestamp_ms;
  var sortedCounters = getSortedKeys(detail.counters);
  $.each(sortedCounters, function(index, key) {
    var value = detail.counters[key];
    // Round to 2 decimal places.
    var avgRate = Math.round(100.0 * value / (runtimeMs / 1000.0)) / 100.0;
    $('<li>')
      .append($('<span class="param-key">').html(getNiceParamKey(key)))
      .append($('<span>').text(': '))
      .append($('<span class="param-value">').html(value))
      .append($('<span>').text(' '))
      .append($('<span class="param-aux">').text('(' + avgRate + '/sec avg.)'))
      .appendTo(aggregatedCounters);
  });

  // Set up the mapper detail.
  var mapperBody = $('#mapper-shard-status');
  mapperBody.empty();

  $.each(detail.shards, function(index, shard) {
    var row = $('<tr>');

    row.append($('<td>').text(shard.shard_number));

    var status = (shard.active ? 'running' : shard.result_status) || 'unknown';
    row.append($('<td>').text(status));

    // TODO: Set colgroup width for shard description.
    row.append($('<td>').text(shard.shard_description));

    row.append($('<td>').text(shard.last_work_item || 'Unknown'));

    row.append($('<td>').text(getElapsedTimeString(
        detail.start_timestamp_ms, shard.updated_timestamp_ms)));

    row.appendTo(mapperBody);
  });
}

function initJobDetail(jobId, detail) {
  // Set titles.
  var title = 'Status for "' + detail.name + '"-- Job #' + jobId;
  $('head > title').text(title);
  $('#detail-page-title').text(detail.name);
  $('#detail-page-undertext').text('Job #' + jobId);

  // Set control buttons.
  if (self != top) {
    $('#overview-link').hide();
  }
  if (detail.active) {
    var control = $('<a href="">')
      .text('Abort Job')
      .click(function(event) {
        abortJob(detail.name, jobId);
        event.stopPropagation();
        return false;
      });
    $('#job-control').append(control);
  } else {
    var control = $('<a href="">')
      .text('Cleanup Job')
      .click(function(event) {
        cleanUpJob(detail.name, jobId);
        event.stopPropagation();
        return false;
      });
    $('#job-control').append(control);
  }

  refreshJobDetail(jobId, detail);
}

//////// Detail page entry point.
function initDetail() {
  var jobId = getJobId();
  if (!jobId) {
    setButter('Could not find job ID in query string.', true);
    return;
  }
  getJobDetail(jobId, initJobDetail);
}
