/*
 * 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;
}

// Gets a local datestring from a UNIX timestamp in milliseconds.
function getLocalTimestring(timestamp_ms) {
  var when = new Date();
  when.setTime(timestamp_ms);
  return when.toLocaleString();
}

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(getLocalTimestring(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(getLocalTimestring(
          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();
  $('<div>').text('Processed items per shard').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);
}
