{% extends "layouts/content.html" %}
{% load utils %}
{% load humanize %}

{% block styles %}
  <style>
    code {
      margin: 0px;
      padding-top: 0px;
      padding-bottom: 0px;
      border: 0px;
      color: black;
      white-space: pre-wrap;
      display: block;
    }
    .results {
      border: 1px solid black;
      white-space: normal;
    }
    .results_failed {
      border: 2px solid red;
    }
    .exception {
      border: 1px solid red;
    }

    .failure_comment {
      white-space: pre-wrap;
      word-wrap: break-word;
    }

    .feedback {
      color: #555;
      background-color: #e7f0e6;
      border-right: 1px solid grey;
    }

    .btn-keyboard {
      color: #fff;
      background-color: #333;
      border-color: #333;
    }

    .btn-keyboard:hover {
      color: #fff;
      background-color: #000;
      border-color: #000;
    }

    .btn-keyboard.focus {
      color: #fff;
    }

    .btn-feedback {
      color: #555;
      background-color: #e7f0e6;
    }

    .btn-feedback:hover {
      color: #555;
      background-color: #e0f0d9;
    }

    .btn-feedback.focus {
      color: #444;
      background-color: #e0f0d9;
    }

    .affix {
      position: absolute;
      right: 0px;
      overflow: auto;
      background-color: #eee;
      border: 1px solid #ddd;
      border-radius: 4px;
      padding: 3px;
      z-index: 1;
      max-height: 80vh;
    }
    .fix-affix {
      position: fixed;
      right: 0px;
      top: 70px;
    }
    #affix-full {
      display: none;
    }

    .tr-danger {
      color: #c9302c;
      font-weight: bold;
    }
    .tr-warning {
      color: #ec971f;
      font-weight: bold;
    }
    .tickLabel {
      transform: rotate(-30deg);
    }

    .text-white {
      color: white;
    }
    .text-white:hover {
      color: white;
    }
  </style>
{% endblock %}

{% block content %}
<div class="row" id="top">
  <div class="col-md-6">
    <dl class="dl-horizontal">
      <dt>Description</dt>
      <dd>{{ job.description|default:"<i>not set</i>" }}</dd>
      <dt>Device-type</dt>
{% if job.requested_device_type %}
      <dd><a href="{{ job.requested_device_type.get_absolute_url }}">{{ job.requested_device_type }}</a> <a href="{% url 'lava.scheduler.device_type_report' job.requested_device_type %}"><span class="glyphicon glyphicon-stats"></span></a></dd>
{% else %}
      <dd>...</dd>
{% endif %}
      <dt>Submitter</dt>
      <dd><a href="mailto:{{ job.submitter.email }}">{{ job.submitter.get_full_name|default:job.submitter.username }}</a></dd>
      <dt>Created</dt>
      <dd title="{{ job.submit_time }}">{{ job.submit_time|naturaltime }}</dd>
      <dt>Priority</dt>
      <dd>{{ job.get_priority_display }}</dd>
      <dt>Visibility</dt>
      <dd>{{ job.get_visibility_display }}{% if job.visibility == job.VISIBLE_GROUP %} ({{ job.viewing_groups.all|join:', ' }}){% endif %}</dd>
      {% if job_tags %}
      <dt>Required Tags</dt>
      <dd>
      {% for tag in job_tags %}
        {% if tag.description %}
        <abbr title="{{ tag.description }}">{{ tag.name }}</abbr>{% if not forloop.last %},{% endif %}
        {% else %}
        {{ tag.name }}{% if not forloop.last %},{% endif %}
        {% endif %}
      {% endfor %}
      </dd>
      {% endif %}

    </dl>
  </div>
  <div class="col-md-6">
    <dl class="dl-horizontal">
      <dt>#{{ job.sub_id|default:job.id }}</dt>
      {% if job.state != job.STATE_FINISHED %}
      <dd><span id="jobstatus">{{ job.get_state_display }}</span>
      {% elif job.health == job.HEALTH_UNKNOWN %}
      <dd><span class="label label-default">{{ job.get_health_display }}</span>
      {% elif job.health == job.HEALTH_COMPLETE %}
      <dd><span class="label label-success">{{ job.get_health_display }}</span>
      {% elif job.health == job.HEALTH_INCOMPLETE %}
      <dd><span class="label label-danger">{{ job.get_health_display }}</span>
      {% else %}
      <dd><span class="label label-warning">{{ job.get_health_display }}</span>
      {% endif %}
      {% if job.is_multinode %}
        <div class="btn-group">
          <button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">sub jobs <span class="caret"></span></button>
          <ul class="dropdown-menu">
            {% for subjob in job.sub_jobs_list %}
            {% if subjob.id == job.id %}
            <li class="disabled"><a href=".">#{{ subjob.sub_id }} ({{ subjob.device_role }})</a></li>
            {% else %}
            <li><a href="{% url 'lava.scheduler.job.detail' subjob.sub_id %}">#{{ subjob.sub_id }} ({{ subjob.device_role }}): <span id="subjob_{{ subjob.id }}">{{ subjob.get_state_display }}</span></a></li>
            {% endif %}
            {% endfor %}
          </ul>
        </div>
      {% endif %}
      </dd>
      <dt>Device</dt>
      {% if job.actual_device %}
      <dd id="actual_device"><a href="{{ job.actual_device.get_absolute_url }}">{{ job.actual_device.hostname }}</a> <a
      href="{% url 'lava.scheduler.device_report' job.actual_device.pk %}"><span class="glyphicon glyphicon-stats"></span></a></dd>
      {% else %}
      <dd id="actual_device">...</dd>
      {% endif %}
      <dt>Started</dt>
      <dd id="started" title="{{ job.start_time }}">{% if job.start_time %}{{ job.start_time|naturaltime }}{% else %}...{% endif %}</dd>
      <dt>Duration</dt>
      {% if job.state != job.STATE_FINISHED %}
      <dd id="duration">...</dd>
      {% else %}
      <dd id="duration" title="{{ job.duration }}">{{ job.end_time|timeuntil:job.start_time }}</dd>
      {% endif %}
      {% if job.results_link %}
      <dt>Results</dt>
      <dd><a href="{{ job.results_link }}" class="btn btn-success btn-xs">&nbsp;<span class="glyphicon glyphicon-signal"></span>&nbsp;</a></dd>
      {% endif %}
    </dl>
  </div>
</div>

{% if lava_job_result %}
<div class="alert alert-danger">
  <p><strong>{{ lava_job_result.error_type }} error:</strong> {{ lava_job_result.error_msg }}</p>
</div>
{% endif %}
{% if invalid_log_data %}
<div class="alert alert-warning">
  <p><strong>Unable to parse invalid logs:</strong> This is maybe a bug in LAVA that should be reported.</p>
</div>
{% endif %}

{% if job.archived_job_file %}
<div class="alert alert-info">
  <p><strong>Job log file archived</strong> Please contact the administrator for job log file.</p>
</div>
{% endif %}
<div id="failure_block" {% if not job.failure_comment %}style="display: none;" {% endif %}>
  <pre class="alert alert-danger failure_comment">{{ job.failure_comment }}</pre>
</div>
{% if size_warning %}
<div class="alert alert-danger" id="size-warning">
<p><strong>This log file is too large to view</strong>, (over {{ size_warning|filesizeformat }}).
    It can only be downloaded:
<a href="{% url 'lava.scheduler.job.log_file.plain' job.pk %}"><span class="glyphicon glyphicon-save-file"></span> Plain log</a></p>
</div>
{% endif %}
<div class="affix hidden-xs hidden-sm">
  <h4>Pipeline <span class="glyphicon glyphicon-arrow-down" aria-hidden="true"></span></h4>
  <div id="affix-full">
    <ul class="list-unstyled">
      {% include 'lava_scheduler_app/_pipeline_actions.html' with pipeline=pipeline_data %}
    </ul>
  </div>
</div>

<ul class="nav nav-tabs">
  <li class="active"><a href="#Log" data-toggle="tab">Summary</a></li>
  <li><a href="#Description" data-toggle="tab">Description</a></li>
  <li><a href="#Timing" id="TimingButton" data-toggle="tab">Timing</a></li>
  <li class="pull-right"><a href="#bottom">End of page <span class="glyphicon glyphicon-chevron-down"></span></a></li>
</ul>

<div class="tab-content">
  <div class="tab-pane active" id="Log">
{% if not size_warning %}
    <div class="btn-group" data-toggle="buttons" id="logbuttons">
      <label class="btn btn-default" id="debug_label" for="debug"><input type="checkbox" id="debug" autocomplete="off">debug</label>
      <label class="btn btn-info" id="info_label" for="info"><input type="checkbox" id="info" autocomplete="off">info</label>
      <label class="btn btn-warning" id="warning_label" for="warning"><input type="checkbox" id="warning" autocomplete="off">warning</label>
      <label class="btn btn-danger" id="error_label" for="error"><input type="checkbox" id="error" autocomplete="off">error</label>
      <label class="btn btn-keyboard" id="keyboard_label" for="keyboard"><input type="checkbox" id="keyboard" autocomplete="off">input</label>
      <label class="btn btn-success" id="target_label" for="target"><input type="checkbox" id="target" autocomplete="off">output</label>
      <label class="btn btn-feedback" id="feedback_label" for="feedback"><input type="checkbox" id="feedback" autocomplete="off">feedback</label>
      <label class="btn btn-primary" id="results_label" for="results"><input type="checkbox" id="results" autocomplete="off">results</label>
    </div>
{% endif %}

    <div class="btn-group pull-right">
      {% if job.is_multinode %}
      <a class="btn btn-info" href="{% url 'lava.scheduler.job.multinode_definition' job.pk %}">Multinode</a>
      {% else %}
      <a class="btn btn-info" href="{% url 'lava.scheduler.job.definition' job.pk %}">Definition</a>
      {% endif %}
      {% if show_cancel %}
        {% if job.is_multinode %}
      <a class="btn btn-warning" id="cancel" href="{% url 'lava.scheduler.job.cancel' job.sub_id %}">Cancel</a>
        {% else %}
      <a class="btn btn-warning" id="cancel" href="{% url 'lava.scheduler.job.cancel' job.pk %}">Cancel</a>
        {% endif %}
      {% elif show_fail %}
        {% if job.is_multinode %}
      <a class="btn btn-danger" id="fail" title="This should not be used if lava-run is still running" href="{% url 'lava.scheduler.job.fail' job.sub_id %}">Fail</a>
        {% else %}
      <a class="btn btn-danger" id="fail" title="This should not be used if lava-run is still running" href="{% url 'lava.scheduler.job.fail' job.pk %}">Fail</a>
        {% endif %}
      {% endif %}
      {% if show_resubmit %}
      <a class="btn btn-primary" href="{% url 'lava.scheduler.job.resubmit' job.pk %}">Resubmit</a>
      {% endif %}
      <div class="btn-group">
        <button type="button" class="btn btn-danger dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Actions <span class="caret"></span></button>
        <ul class="dropdown-menu">
          {% if job.is_multinode %}
          <li><a href="{% url 'lava.scheduler.job.definition' job.pk %}">Definition</a></li>
          {% endif %}
          <li><a href="{% url 'lava.scheduler.job.log_file.plain' job.pk %}"><span class="glyphicon glyphicon-save-file"></span> Plain log</a></li>
          <li><a href="{% url 'lava.scheduler.job.configuration' job.pk %}"><span class="glyphicon glyphicon-book"></span> Configuration</a></li>
          <li role="separator" class="divider"></li>
          <li><a href="{% url 'lava.scheduler.job.toggle_favorite' job.pk %}"><span class="glyphicon glyphicon-star{% if not is_favorite %}-empty{% endif %}"></span> {{ is_favorite|yesno:"Remove from favorites,Add to favorites" }}</a></li>
          <li><a href="#" data-toggle="modal" data-target="#similar_jobs_modal"><span class="glyphicon glyphicon-search"></span> Similar jobs</a></li>
          {% if show_failure or user.is_superuser %}
          <li role="separator" class="divider"></li>
          {% if show_failure %}
          <li><a href="{% url 'lava.scheduler.job.annotate_failure' job.pk %}">Comment</a></li>
          {% endif %}
          {% if user.is_superuser %}
          <li><a href="{% url 'admin:lava_scheduler_app_testjob_change' job.pk %}">Admin this TestJob</a></li>
          {% endif %}
          {% endif %}
        </ul>
      </div>
    </div>

    <div id="sectionlogs">
      {% for line in log_data %}
        {% if line.lvl == "debug" %}
          {% get_action_id line.msg as act_id %}
      <code class="debug" title="{{ line.dt }}" id="{% if act_id %}action_{{ act_id }}{% else %}L{{ forloop.counter0 }}{% endif %}">{{ line.msg|udecode }}</code>
        {% elif line.lvl == "input" %}
      <code class="keyboard" id="L{{ forloop.counter0 }}" title="{{ line.dt }}"><kbd>{{ line.msg|udecode }}</kbd></code>
        {% elif line.lvl == "target" %}
      <code class="target bg-success" id="L{{ forloop.counter0 }}" title="{{ line.dt }}">{{ line.msg|udecode }}</code>
        {% elif line.lvl == "feedback" %}
      <code class="feedback" id="L{{ forloop.counter0 }}" title="{{ line.dt }}">{{ line.msg|udecode }}</code>
        {% elif line.lvl == "results" %}
            {% if line.msg.set %}
              {% url 'lava.results.testset' job.id line.msg.definition line.msg.set line.msg.case as result_url %}
            {% else %}
              {% url 'lava.results.testcase' line.msg.case_id as result_url %}
            {% endif %}
      <code class="results bg-primary{% if line.msg.result == "fail" %} results_failed{% endif %}" id="results_{{ line.msg.case_id }}">
        <a class="text-white" href="{{ result_url|default:"#invalid_test_name" }}">
        {% for key, value in line.msg.items|sort_items %}
          {% if value.items %}
            {% if key == "extra" %}
              extra: ...<br />
            {% else %}
              {% for k, v in value.items %}
                {{ k }}: {{ v }}<br />
              {% endfor %}
            {% endif %}
          {% else %}
              {{ key }}: {{ value }}<br />
          {% endif %}
        {% endfor %}
        </a></code>
        {% elif line.lvl == "error" or line.lvl == "exception" %}
      <code class="{{ line.lvl }} bg-danger" id="L{{ forloop.counter0 }}" title="{{ line.dt }}">{{ line.msg|udecode }}</code>
        {% else %}
          {% get_action_id line.msg as act_id %}
      <code class="{{ line.lvl }} bg-{{ line.lvl }}" id="{% if act_id %}action_{{ act_id }}{% else %}L{{ forloop.counter0 }}{% endif %}" title="{{ line.dt }}">{{ line.msg|udecode }}</code>
        {% endif %}
      {% endfor %}
      {% if job.state != job.STATE_FINISHED %}
      <img id="log-messages" src="{{ STATIC_URL }}lava_scheduler_app/images/ajax-loader.gif" />
      {% endif %}
    </div>
    {% if not size_warning %}
    <p class="pull-right"><a href="#top">Top of page <span class="glyphicon glyphicon-chevron-up"></span></a></p>
    {% if job.state == job.STATE_FINISHED %}
    <p><a href="{{ STATIC_URL }}docs/v2/debugging.html">Please read the triage guidelines</a> for help on debugging failures in the test job, test definitions or in individual test cases.</p>
    {% endif %}
    {% endif %}
  </div>
  <div class="tab-pane" id="Description">
    <h2>Job Description <a class="btn btn-xs btn-info" href="{% url 'lava.scheduler.job.description.yaml' job.id %}" title="Download YAML description">
      <span class="glyphicon glyphicon-download"></span> YAML</a></h2>
    <p><a href="{{ STATIC_URL }}docs/v2/glossary.html#term-pipeline">Pipeline</a> jobs use
     the job definition to generate a descriptive YAML file when the pipeline is validated.
     The file represents the data sent to the dispatcher at the start of the job, including
     details of the device as well as the job parameters and the details of the parameters
     sent to each of the deploy, boot and test actions in the job pipeline.</p>
     <p>Click on the Device or Job Actions headings below to see some of the information
     from the description file for this job or download the complete file as YAML using
     the link above.</p>
    <div class="panel-group" id="job_accordion">
      <div class="panel panel-default">
        <div class="panel-heading">
          <h4 class="panel-title"><a data-toggle="collapse" data-parent="#job_accordion" href="#device_collapse">Device</a></h4>
        </div>
        <div id="device_collapse" class="panel-collapse collapse{% if 'section' not in request.GET %} in{% endif %}">
          <div class="panel-body">
            <dl class="dl-horizontal">
              <dt>device type</dt>
              <dd>{{ device_data.device_type }}</dd>
              <dt>hostname</dt>
              <dd>{{ device_data.hostname }}</dd>
              <dt>timeouts</dt>
              <dd>
                <ul>
                  {% for key, value in device_data.timeouts.items %}
                  <li>{{ key }}: {{ value.values|join:'' }} {{ value.keys|join:'' }}</li>
                  {% endfor %}
                </ul>
              </dd>
              <dt>device action methods</dt>
              <dd>
                {% for key, value in device_data.actions.items %}
                {{ key }}:
                <ul>
                  {% for itemkey, itemvalue in value.methods.items %}
                  <li>{{ itemkey }}:
                    <ul>
                      {% for paramkey, paramvalue in itemvalue.parameters.items %}
                      <li>{{ paramkey }}: {{ paramvalue }}</li>
                      {% endfor %}
                    </ul>
                  </li>
                {% endfor %}
                </ul>
                {% endfor %}
              </dd>
            </dl>
          </div>
        </div>
      </div>
      <div class="panel panel-default">
        <div class="panel-heading">
          <h4 class="panel-title"><a data-toggle="collapse" data-parent="#job_accordion" href="#job_actions">Job Actions</a></h4>
        </div>
        <div id="job_actions" class="panel-collapse collapse{% if 'section' in request.GET %} in{% endif %}">
          <div class="panel-body">

            <!-- Here we insert another nested accordion -->
            <dl class="dl-horizontal">
              <dt>target</dt>
              <dd>{{ job_data.target|default:'...' }}</dd>
              <dt>timeouts</dt>
              <dd>
                {% if job_data.timeouts %}
                <ul>
                  {% for key, value in job_data.timeouts.items %}
                  <li>{{ key }}: {{ value }}</li>
                  {% endfor %}
                </ul>
                {% else %}...
                {% endif %}
              </dd>
            </dl>
            <div class="panel-group" id="action_list">
              <div class="panel panel-default">
                <div class="panel-heading">
                  <h4 class="panel-title"><a data-toggle="collapse" data-parent="#action_list" href="#collapseInnerOne">Deploy</a></h4>
                </div>
                <div id="collapseInnerOne" class="panel-collapse collapse{% if 'section' in request.GET and request.GET.section == 'deploy' %} in{% endif %}">
                  <div class="panel-body">
                    <ol>
                      {% for entry in deploy_list %}
                      <li><br/>
                        <dl class="dl-horizontal">
                          {% for key, value in entry.items %}
                          {% if key == 'timeout' %}
                          <dt>Timeout</dt>
                          <dd>
                            <ul>
                              {% for timekey, timevalue in value.items %}
                              {% if timekey == 'yaml_line' %}
                              <li>{{ timekey }} {{ timevalue }}</li>
                              {% else %}
                              <li>{{ timevalue }} {{ timekey }}</li>
                              {% endif %}
                              {% endfor %}
                            </ul>
                          </dd>
                          {% else %}
                          <dt>{{ key }}</dt>
                          <dd>{{ value }}</dd>
                          {% endif %}
                          {% endfor %}
                        </dl>
                      </li>
                      {% endfor %}
                    </ol>
                  </div>
                </div>
              </div>
              <div class="panel panel-default">
                <div class="panel-heading">
                  <h4 class="panel-title"><a data-toggle="collapse" data-parent="#action_list" href="#collapseInnerTwo">Boot</a></h4>
                </div>
                <div id="collapseInnerTwo" class="panel-collapse collapse{%if 'section' in request.GET and request.GET.section == 'boot' %} in{% endif %}">
                  <div class="panel-body">
                    <ol>
                    {% for entry in boot_list %}
                      <li><br/>
                        <dl class="dl-horizontal">
                          {% for key, value in entry.items %}
                          {% if key == 'timeout' %}
                          <dt>Timeout</dt>
                          <dd>
                            <ul>
                              {% for timekey, timevalue in value.items %}
                              {% if timekey == 'yaml_line' %}
                              <li>{{ timekey }} {{ timevalue }}</li>
                              {% else %}
                              <li>{{ timevalue }} {{ timekey }}</li>
                              {% endif %}
                              {% endfor %}
                            </ul>
                          </dd>
                          {% else %}
                          <dt>{{ key }}</dt>
                          <dd>{{ value }}</dd>
                          {% endif %}
                          {% endfor %}
                        </dl>
                      </li>
                    {% endfor %}
                    </ol>
                  </div>
                </div>
              </div>
              <div class="panel panel-default">
                <div class="panel-heading">
                  <h4 class="panel-title"><a data-toggle="collapse" data-parent="#action_list" href="#collapseInnerThree">Test</a></h4>
                </div>
                <div id="collapseInnerThree" class="panel-collapse collapse{% if 'section' in request.GET and request.GET.section == 'test' %} in{% endif %}">
                  <div class="panel-body">
                    <ol>
                      {% for entry in test_list %}
                      <li><br/>
                        <dl class="dl-horizontal">
                          {% for key, value in entry.items %}
                          {% if key == 'timeout' %}
                          <dt>Timeout</dt>
                          <dd>
                            <ul>
                              {% for timekey, timevalue in value.items %}
                              {% if timekey == 'yaml_line' %}
                              <li>{{ timekey }} {{ timevalue }}</li>
                              {% else %}
                              <li>{{ timevalue }} {{ timekey }}</li>
                              {% endif %}
                              {% endfor %}
                            </ul>
                          </dd>
                          {% elif key == 'definitions' %}
                          <dt>Definitions</dt>
                          <dd>
                            {% for item in value %}
                            <ul>
                              {% for elem_key, elem_value in item.items %}
                              <li>{{ elem_key }} {{ elem_value }}</li>
                              {% endfor %}
                            </ul>
                            {% endfor %}
                          </dd>
                          {% else %}
                          <dt>{{ key }}</dt>
                          <dd>{{ value }}</dd>
                          {% endif %}
                          {% endfor %}
                        </dl>
                      </li>
                      {% endfor %}
                    </ol>
                  </div>
                </div>
              </div>
            </div>
            <!-- Inner accordion ends here -->
          </div>
        </div>
      </div>
    </div>
  </div>

  <div class="tab-pane" id="Timing">
    <h2>Job Timings</h2>
    <p>This section helps test writers to check for actions with a duration which
       is much shorter than the requested timeout.  Reducing these timeouts
       will allow failures to be identified more quickly.</p>
    <p>The graph only shows actions that are longer than 1 second. The full list
       is anyway available in the table.</p>

    <div id="timing_block">Loading the data...</div>
  </div>

</div>

{% include "_similar_jobs.html" %}
<div id="bottom"></div>
{% endblock %}

{% block scripts %}
<script type="text/javascript">
  var condition_choices = JSON.parse($("#id_condition_choices").val());
  var content_types = JSON.parse($("#id_available_content_types").val());
</script>
<script type="text/javascript" src="{{ STATIC_URL }}lava_scheduler_app/js/anchor-v3.2.0.min.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}lava_server/js/jquery.typeahead.min.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}lava_scheduler_app/js/similar-jobs.min.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}lava_scheduler_app/js/jquery.flot.min.js"></script>
<script type="text/javascript">
  $(document).ready(
    function() {
{% if not size_warning %}
      // Create a new CSS sheet and use it
      var sheet = (function() {
        var style = document.createElement("style");
        // WebKit hack :(
        style.appendChild(document.createTextNode(""));
        document.head.appendChild(style);
        return style.sheet;
      })();

      // Create the list of styles
      // Debug are deactivated by default
      var styles = {
        'debug': sheet.insertRule('.debug { display: block }', 0),
        'keyboard': sheet.insertRule('.keyboard { display: block }', 1),
        'info': sheet.insertRule('.info { display: block }', 2),
        'warning': sheet.insertRule('.warning { display: block }', 3),
        'error': sheet.insertRule('.error { display: block }', 4),
        'target': sheet.insertRule('.target { display: block }', 5),
        'results': sheet.insertRule('.results { display: block }', 6),
        'feedback': sheet.insertRule('.feedback { display: block }', 7),
      };

      // Handle click events on buttons
      $("#logbuttons label").click(function(e) {
        var label = e.target.htmlFor;
        var input = $('input#' + label);
        var rule;
        if (input.is(':checked')) {
          rule = '.' + label + ' { display: block }';
          $('label#' + label + '_label').css('text-decoration', 'None');
        } else {
          rule = '.' + label + ' { display: none }';
          $('label#' + label + '_label').css('text-decoration', 'line-through');
        }
        // Remove old style and insert the new one
        var index = styles[label];
        sheet.deleteRule(index);
        sheet.insertRule(rule, index);
      });

      // Open the affix if the user click on the button
      var affix_toggle = true;
      $('.affix h4').click(function() {
        if(affix_toggle) {
          $('#affix-full').css('display', 'block');
          $('.affix span').removeClass('glyphicon-arrow-down');
          $('.affix span').addClass('glyphicon-arrow-up');
        } else {
          $('#affix-full').css('display', 'none');
          $('.affix span').removeClass('glyphicon-arrow-up');
          $('.affix span').addClass('glyphicon-arrow-down');
        }
        affix_toggle = !affix_toggle;
      });

      // Move the affix
      var affix = $('.affix');
      var affix_top = window.scrollY +
                      $('.affix h4')[0].getBoundingClientRect().top - 70;
      // Place it correctly if the page is reloaded while not at the top
      if (document.body.scrollTop > affix_top ||
          document.documentElement.scrollTop > affix_top) {
        affix.addClass("fix-affix");
      }
      $(window).scroll(function(e) {
        if (document.body.scrollTop > affix_top ||
            document.documentElement.scrollTop > affix_top) {
          affix.addClass("fix-affix");
        } else {
          affix.removeClass("fix-affix");
        }
      });
{% endif %}

      // Load the timing on demand
      var timing_already_loaded = false;
      $("#TimingButton").click(function(e) {
        if (timing_already_loaded) { return; }
        $.ajax({
          url: '{% url 'lava.scheduler.job.timing' pk=job.pk %}',
          error: function(xhr, txt_status, error) {
            $('#timing_block').html("<p><strong>Unable to load the timing!</strong</p>");
          },
          success: function(data, success, xhr) {
            if (data['graph'].length == 0) {
              $('#timing_block').html("<p>Unable to parse the log file.</p>");
              return;
            }
            $('#timing_block').html(data['timing']);
            // Generate the graph
            var durations = [];
            var timeouts = [];
            var levels = [];
            for(var i = 0; i < data['graph'].length; i++) {
              if (data['graph'][i][2] <= 1) { continue; }
              durations.push([i, data['graph'][i][2]]);
              timeouts.push([i, data['graph'][i][3]]);
              levels.push([i, data['graph'][i][0]]);
            }

            var ddata = [
              {'label': 'duration', 'data': durations, 'color': '#FF0000'},
              {'label': 'timeout', 'data': timeouts, 'color': '#0000FF'},
            ];

            $.plot($("#timings"), ddata, {
              series: {
                lines: { show: true, fill: true, steps: false },
              },
              xaxis: {
                ticks: levels,
              },
            });
          }
        });
        timing_already_loaded = true;
      })
    });

    {% if job.state == job.STATE_FINISHED %}
    // Add the links only for non-running jobs
    anchors.options.placement = 'left';
    anchors.add('code');
    {% endif %}

{% if job.state != job.STATE_FINISHED %}
  // Add a timer for the log updates
  pollTimer = setTimeout(poll, 5000);
{% endif %}

  var poll_status = 1;
  var poll_logs = 1;
  var position = {{ log_data|length }};
  var progressNode = $('#log-messages');
  var action_id_regexp = /^start: ([\d.]+) [\w_-]+ /;
  function poll() {
    // Update job status
    if(poll_status) {
      $.ajax({
        url: '{% url 'lava.scheduler.job_status' pk=job.pk %}',
        success: function(data, success, xhr) {
          $('#actual_device').html(data['actual_device']);
          $('#started').html(data['started']);
          $('#jobstatus').html(data['job_state']);
          $('#duration').html(data['duration']);
          for(var i = 0; i < data['subjobs'].length; i++) {
            var d = data['subjobs'][i];
            $('#subjob_' + d[0]).html(d[1]);
          }
          if ('X-JobState' in data) {
            $('#cancel').css('display', 'none');
            $('#fail').css('display', 'none');
            poll_status = 0;
          }
          if (data['failure_comment']) {
            $("#failure_block").show();
            $(".failure_comment").html(data['failure_comment']);
          }
        }
      });
    }

    // Update logs
    if(poll_logs) {
      $.ajax({
        url: '{% url 'lava.scheduler.job.log_incremental' pk=job.pk %}?line=' + position,
        success: function(data, success, xhr) {
          // Do we have to scroll down ?
          var scroll_down = false;
          if((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
            scroll_down = true;
          }

          // Loop on all new code blocks
          for(var i = 0; i < data.length; i++) {
              var d = data[i];
              var level = d['lvl'];
              var id = "L" + (position + i);

              var node;
              if(level == 'debug') {
                var action_id = action_id_regexp.exec(d['msg']);
                if(action_id) {
                  id = 'action_' + action_id[1].replace(/\./g, '-');
                }
                $('<code class="debug" id="' + id + '"></code>')
                  .text(d['msg'])
                  .insertBefore(progressNode);
              } else if(level == 'input') {
                $('<code class="keyboard" id="' + id + '"></code>')
                  .append($('<kbd></kbd>')
                  .text(d['msg']))
                  .insertBefore(progressNode);
              } else if(level == 'target') {
                $('<code class="target bg-success" id="' + id + '"></code>')
                  .text(d['msg'])
                  .insertBefore(progressNode);
              } else if(level == 'feedback') {
                $('<code class="feedback" id="' + id + '"></code>')
                  .text(d['msg'])
                  .insertBefore(progressNode);
              } else if(level == 'results') {
                id = 'results_' + d['msg']['definition'] + '_' + d['msg']['case'] + '_F_' + d['msg']['result'];
                // TODO: not working with MOUNT_POINT
                var link = $('<a href="/results/testcase/' + d['msg']['case_id'] + '"></a>');
                var node;
                if(d['msg']['result'] == 'fail') {
                  node = $('<code class="results bg-primary results_failed" id="' + id + '"></code>');
                } else {
                  node = $('<code class="results bg-primary" id="' + id + '"></code>');
                }
                for(key in d['msg']) {
                  if(typeof(d['msg'][key]) == 'string') {
                    node.append($('<span></span>').text(key + ': ' + d['msg'][key]));
                    node.append($('<br />'));
                  } else if(key == 'extra') {
                    node.append($('<span>extra: ...</span><br />'));
                  } else {
                    for(k in d ['msg'][key]) {
                      node.append($('<span></span>').text(k + ': ' + d['msg'][key][k]));
                      node.append($('<br />'));
                    }
                  }
                }
                link.append(node);
                link.insertBefore(progressNode);
              } else if (level == 'error' || level == 'exception' ) {
                $('<code class="' + level + ' bg-danger" id="' + id + '"></code>')
                  .text(d['msg'])
                  .insertBefore(progressNode);
              } else {
                var action_id = action_id_regexp.exec(d['msg']);
                if(action_id) {
                  id = 'action_' + action_id[1].replace(/\./g, '-');
                }
                $('<code class="' + level + ' bg-' + level + '" id="' + id + '"></code>')
                  .text(d['msg'])
                  .insertBefore(progressNode);
              }
          }
          // Relaunch the timer
          if(xhr.getResponseHeader('X-Is-Finished')) {
            $('#log-messages').css('display', 'none');
            poll_logs = 0;
          } else {
            position += data.length
          }

          // Scroll down
          if (scroll_down) {
            document.getElementById('bottom').scrollIntoView();
          }
        }
      });
    }
    if(poll_status || poll_logs) {
      pollTimer = setTimeout(poll, 5000);
    }
  };
</script>
{% endblock scripts %}
