<%inherit file="master.html"/>
<%namespace name="json" module="json"/>
<%
  from urllib.parse import urljoin

  from bodhi.server import models

  from bodhi.server.config import config

  install_command = update.install_command
%>

<%block name="pagetitle">
  ${update.alias}
&mdash;
${update.type} update for ${update.get_title(amp=True,beautify=True) | h}
&mdash; Fedora Updates System
</%block>

<%  update.bugs.sort(key = lambda x: x.bug_id)  %>

<%block name="css">
${parent.css()}
<link rel="alternate" type="application/atom+xml" title="New Comments on ${update.alias}" href="${request.route_url('comments_rss')}?updates=${update.alias}"/>
<link href="${request.static_url('bodhi:server/static/vendor/messenger/css/messenger.css') }" rel="stylesheet" />
<link href="${request.static_url('bodhi:server/static/vendor/messenger/css/messenger-theme-flat.css') }" rel="stylesheet" />
</%block>

<%
actions = {}
if can_edit and update.release.composed_by_bodhi:
  if not update.locked:
    if not update.pushed:
      if update.request is None:
        if update.status.value != 'testing':
          actions['push to testing'] = True
      else:
        actions['revoke'] = True
    elif update.pushed and (update.status.value != 'stable' or (update.status.value == 'stable' and 'releng' in [group.name for group in request.user.groups])):
      if update.request:
        actions['revoke'] = True
      actions['unpush'] = True
      if update.meets_testing_requirements and not update.request:
        actions['push to stable'] = True
%>
<div class="subheader pt-3">
<div class="container">
<div class="row">
  <div class="col-md-12">
    <div class="h3">
      <div class="row">
        <div class="col">
            <div class="media">
              <div class="text-center">
                % if update.type:
                  ${self.util.type2icon(update.type) | n}
                % endif
                % if update.critpath:
                <br/><span data-toggle="tooltip" title="This update is in the critical path" class="ml-n2 text-muted"><small> <i class="fa fa-fw fa-fire"></i></small></span>
                % endif
            </div>
                <div class="media-body ml-0">
                    <div class="font-weight-bold">
                      <a href="${request.route_url('update', id=update['alias'])}">
                      ${update.get_title(amp=True,nvr=True,beautify=True) | h}
                      </a>
                    </div>
                    <div class="h5 mt-1">
                        ${update.alias} created by <a href="${request.route_url('user', name=update['user']['name'])}"> ${update['user']['name']}</a>
                        <span title="${update['date_submitted']} UTC"> ${self.util.age(update['date_submitted'])} </span>
                        for <a href="${request.route_url('release', name=update['release']['name'])}">${update['release']['long_name']}
                        </a>
                      </div>
                </div>
            </div>

        </div>
        <div class="col-x-auto">
            % if can_edit and (not update.locked and update.status.value != 'stable'):
              <a id='edit' href="javascript:void(0)" class="btn btn-outline-primary border-0 btn-sm"><span class="fa fa-fw fa-pencil-square-o"></span> Edit</a>
            % elif update.locked and update.date_locked:
            <a class="btn btn-link text-muted" href="${request.route_url('composes', release_name=update.compose.release.name, request=update.compose.request.value)}" data-toggle="tooltip" title="This update is currently locked since ${(update.date_locked).strftime('%Y-%m-%d %H:%M:%S')} (UTC) and cannot be modified.">
              <span class="fa fa-fw fa-lock text-muted"></span>
              <span class="sr-only">Locked</span>
            </a>
            % endif
              <span class="btn btn-sm btn-${self.fragments.status_context(update.status.value)}">
                  ${self.fragments.status_text(update)}
              </span>
            % if actions:
              <div class="dropdown d-inline" id="updatebuttons">
                <button class="btn btn-outline-primary border-0 btn-sm dropdown-toggle" type="button" id="statusActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                    Actions
                </button>
                <div class="dropdown-menu" aria-labelledby="statusActions">
                  %if "push to testing" in actions:
                    <a class="dropdown-item" id="testing" href="javascript:void(0)">Push to Testing</a>
                  %endif
                  %if "revoke" in actions:
                    <a class="dropdown-item" id="revoke" href="javascript:void(0)">Revoke</a>
                  %endif
                  %if "unpush" in actions:
                    <a class="dropdown-item" id="unpush" href="javascript:void(0)">Unpush</a>
                  %endif
                  %if "push to stable" in actions:
                    <a class="dropdown-item" id="stable" href="javascript:void(0)">Push to Stable</a>
                  %endif
                </div>
              </div>
            % endif
        </div>
      </div>
    </div>
  </div>
</div>
<ul class="nav nav-tabs pt-2" role="tablist">
  <li class="nav-item">
    <a class="nav-link active" data-toggle="tab" href="#details" role="tab">Details</a>
  </li>

  <li class="nav-item">
    <a class="nav-link" data-toggle="tab" href="#packages" role="tab">Builds <span class="badge badge-secondary">${len(update.builds)}</span></a>
  </li>

  % if update.bugs:
  <li class="nav-item">
    <a class="nav-link" data-toggle="tab" href="#bugs" role="tab">Bugs <span class="badge badge-secondary">${len(update.bugs)}</span></a>
  </li>
  % endif

  % if update.test_cases:
  <li class="nav-item">
    <a class="nav-link" data-toggle="tab" href="#tests" role="tab">Test Cases <span class="badge badge-secondary">${len(update.test_cases)}</span></a>
  </li>
  % endif

  <li class="nav-item">
    <a class="nav-link" id="tab-automatedtests" data-toggle="tab" href="#automatedtests" role="tab">
      Automated Tests
      <span style="display:none" class='badge badge-success'>
        <span class='fa fa-check-circle'></span>
        <span id="automatedtests-success"></span>
      </span>
      <span style="display:none" class='badge badge-info'>
        <span class='fa fa-info-circle'></span>
        <span id="automatedtests-info"></span>
      </span>
      <span style="display:none" class='badge badge-warning'>
        <span class='fa fa-exclamation-circle'></span>
        <span id="automatedtests-warning"></span>
      </span>
      <span style="display:none" class='badge badge-danger'>
        <span class='fa fa-minus-circle'></span>
        <span id="automatedtests-danger"></span>
      </span>
      <span id="automatedtests-progress" class="badge badge-secondary"></span>
    </a>
  </li>

</ul>
</div>
</div>
<div class="container pt-4">
  <!-- Tab panes -->
  <div class="tab-content">
    <div class="tab-pane active" id="details" role="tabpanel">
      <div class="row">
        <div class="col-9">

          % if update.notes:
          ${self.util.markup(update.notes) | n}
          % endif

          % if not 'unspecified' in update.suggest:
          <p class="mt-3">
            % if 'logout' in update.suggest:
            <h5 class="font-weight-bold"><i class="fa fa-exclamation-circle text-muted"></i> Logout Required</h5>
            After installing this update it is required that you logout of
            your current user session and log back in to ensure the changes
            supplied by this update are applied properly.
            % elif 'reboot' in update.suggest:
            <h5 class="font-weight-bold"><i class="fa fa-exclamation-circle text-muted"></i> Reboot Required</h5>
            After installing this update it is required that you reboot your
            system to ensure the changes supplied by this update are applied
            properly.
            % endif
          </p>
          % endif

          % if install_command:
          <div class="pt-2">
          <h4>How to install</h4>
            <pre style="position: relative;"><span class="badge badge-secondary" id="copybutton" style="position: absolute; top: 0px; right: 0px; cursor: pointer;" title="Copy to clipboard"><i class="fa fa-copy"></i></span><code id="commandtext">${install_command}</code></pre>
          </div>
          % endif

          <div class="pt-2 mt-4 border-top">
            <!--<h4>Comments <span class="badge badge-secondary">${len(update.comments)}</span>
              <small><a href="${request.route_url('comments_rss')}?updates=${update.alias}">
                  <span class="fa fa-rss"></span>
              </a></small>
            </h4>-->
            <div id="comments">
              % for comment in update.comments:
              <div id="comment-${comment.id}">
                ${self.fragments.comment(comment, display_update=False)}
              </div>
              % endfor
            </div>
          </div>
          <hr/>
          % if request.user:
          <div id="new_comment">
          <input type="hidden" name="csrf_token" value="${request.session.get_csrf_token()}"/>
          <input type="hidden" name="update" value="${update.alias}"/>
          <div class="card mt-5">
              <div class="card-header pb-0 pt-1 pr-0 bg-light">
                <div class="row">
                  <div class="col pr-0">
                    <%
                      help_content = "Comments support Fedora-Flavored Markdown"
                      if request.registry.settings.get('privacy_link'):
                        help_content = help_content + "<br/><br/>Comments are governed under <a href='${request.registry.settings.get('privacy_link')}'>this privacy policy</a>."
                    %>
                      <a tabindex="0" class="btn btn-link text-muted float-right" role="button" data-toggle="popover" data-trigger="focus" title="Comment Help"
                      data-content="${help_content}" data-html="true" data-placement="bottom">
                      <i class="fa fa-question-circle"></i></a>
                          <ul class="nav nav-tabs float-right border-bottom-0">
                            <li class="nav-item">
                              <a class="nav-link pointer" id="preview_button">Preview</a>
                            </li>
                            <li class="nav-item">
                              <a class="nav-link active pointer" id="edit_button">Edit</a>
                            </li>
                          </ul>
                  </div>
                </div>
              </div>
              <div class="card-body p-0">
                <textarea class="form-control border-0" rows="8" id="text" name="text" placeholder="Enter your comment here" tabindex="1"></textarea>
                <div id="preview" class="p-3 comment-preview" style="display: none;">
                </div>
              </div>
                  <div class="list-group list-group-flush">
                    <div class="list-group-item bg-light py-1">
                      <div class="row">
                        <div class="col-auto min-width-35">${self.fragments.karma(-1)}</div>
                        <div class="col-auto min-width-35">${self.fragments.karma(0)}</div>
                        <div class="col-auto min-width-35">${self.fragments.karma(1)}</div>
                      </div>
                    </div>
                    <div class="list-group-item py-1">
                      <div class="row">
                        <div class="col-auto min-width-35"><input type="radio" name="karma" value="-1"></div>
                        <div class="col-auto min-width-35"><input type="radio" name="karma" value="0" checked></div>
                        <div class="col-auto min-width-35"><input type="radio" name="karma" value="1"></div>
                        <div class="col font-size-09"><strong>Karma:</strong> Is the update generally functional?</div>
                      </div>
                    </div>
                    % if update.bugs:
                    <div class="list-group-item bg-light py-1">
                      <div class="row">
                        <div class="col-auto min-width-35">${self.fragments.karma(-1)}</div>
                        <div class="col-auto min-width-35">${self.fragments.karma(0)}</div>
                        <div class="col-auto min-width-35">${self.fragments.karma(1)}</div>
                        <div class="col font-weight-bold text-muted">Bugs</div>
                      </div>
                    </div>
                    % for bug in update.bugs:
                    <div class="list-group-item py-1">
                      <div class="row">
                        <input type="hidden" name="bug_feedback.${loop.index}.bug_id" value="${bug.bug_id}">
                        <div class="col-auto min-width-35"><input type="radio" name="bug_feedback.${loop.index}.karma" value="-1"></div>
                        <div class="col-auto min-width-35"><input type="radio" name="bug_feedback.${loop.index}.karma" value="0" checked></div>
                        <div class="col-auto min-width-35"><input type="radio" name="bug_feedback.${loop.index}.karma" value="1"></div>
                        <div class="col font-size-09">${self.util.bug_link(bug) | n}</div>
                      </div>
                    </div>
                    % endfor
                    % endif
                    % if update.full_test_cases:
                    <div class="list-group-item bg-light py-1">
                      <div class="row">
                        <div class="col-auto min-width-35">${self.fragments.karma(-1)}</div>
                        <div class="col-auto min-width-35">${self.fragments.karma(0)}</div>
                        <div class="col-auto min-width-35">${self.fragments.karma(1)}</div>
                        <div class="col font-weight-bold text-muted">Test Cases</div>
                      </div>
                    </div>
                    % for test in update.full_test_cases:
                    <div class="list-group-item py-1">
                      <div class="row">
                        <input type="hidden" name="testcase_feedback.${loop.index}.testcase_name" value="${test.name}">
                        <div class="col-auto min-width-35"><input type="radio" name="testcase_feedback.${loop.index}.karma" value="-1"></div>
                        <div class="col-auto min-width-35"><input type="radio" name="testcase_feedback.${loop.index}.karma" value="0" checked></div>
                        <div class="col-auto min-width-35"><input type="radio" name="testcase_feedback.${loop.index}.karma" value="1"></div>
                        <div class="col font-size-09">${self.util.testcase_link(test) | n}</div>
                      </div>
                    </div>
                    % endfor
                    % endif
                  </div>
                  <div class="card-body">

                <div class="d-flex align-items-center">
                  <div class="ml-auto">
                      <button id="submit" type="submit" class="btn btn-outline-primary">
                          <span class="indicator fa fa-comment" data-spinclass="indicator fa fa-spinner fa-spin"></span>
                          Add Comment &amp; Feedback
                        </button>
                  </div>
                </div>
              </div>
            </div>
          </div>
          % else:
          <div class="alert alert-secondary bg-light mt-5 text-center text-muted">
            <p>
            % if request.matched_route:
              Please <a href="${request.route_url('login') + '?came_from=' + request.current_route_url()}">login</a> to add feedback.
            % else:
              Please <a href="${request.route_url('login')}">login</a> to add feedback.
            % endif
            </p>
          </div>
          %endif
        </div>
        <div class="col-3 font-size-09">
            <div class="mt-3">
              <div class="h5 d-flex align-items-center font-weight-bold border-bottom">
                  <div class="py-2 text-uppercase font-size-09">Metadata</div>
              </div>
              
              % if update.type:
              <div class="pb-1">
                  <div class="row">
                    <div class="col font-weight-bold text-muted">Type</div>
                    <div class="col-xs-auto font-weight-bold">
                        ${self.util.type2icon(update.type) | n} ${update.type.value}
                    </div>
                  </div>
              </div>
              % endif

              % if update.severity and update.severity.value != 'unspecified':
              <div class="pb-1">
                  <div class="row">
                    <div class="col font-weight-bold text-muted">Severity</div>
                    <div class="col-xs-auto font-weight-bold">
                        ${update.severity.value}
                    </div>
                  </div>
              </div>
              % endif

              <div class="pb-1">
                  <div class="row">
                    <div class="col font-weight-bold text-muted">Karma</div>
                    <div class="col-xs-auto font-weight-bold">
                        ${self.fragments.karma(update.karma, show_digit=True)}
                    </div>
                  </div>
              </div>

              % if update.signed:
              <div class="pb-1">
                  <div class="row">
                    <div class="col font-weight-bold text-muted">Signed</div>
                    <div class="col-xs-auto font-weight-bold">
                        <span class="fa fa-check text-success" aria-hidden="true" data-toggle="tooltip" data-placement="top" title="Update signed"></span>
                    </div>
                  </div>
              </div>
              % endif

              % if update.content_type:
              <div class="pb-1">
                  <div class="row">
                    <div class="col font-weight-bold text-muted">Content Type</div>
                    <div class="col-xs-auto font-weight-bold">
                        ${update.content_type.description | n}
                    </div>
                  </div>
              </div>
              % endif
            </div>
              % if request.registry.settings.get('test_gating.required'):
              <div class="mt-3">
                  <div class="h5 d-flex align-items-center font-weight-bold border-bottom">
                      <div class="py-2 text-uppercase font-size-09">
                          % if request.registry.settings.get('test_gating.url'):
                          <a class="notblue" href="${request.registry.settings.get('test_gating.url')}" title="More information about test gating">
                            Test Gating
                          </a>
                        % else:
                          Test Gating
                        % endif
                      </div>
                    </div>
              <div class="pb-1">
                <div>
                  % if can_edit and self.util.can_waive_test_results(update):
                  <a id='waive' class="btn btn-sm btn-primary hidden" data-toggle="modal" data-target="#waive_test_results">Waive Test Results</a>
                  % endif
                </div>
                <div>
                  % if can_edit and config.get('test_gating.required'):
                  <a id='trigger' class="btn btn-sm btn-primary hidden" data-toggle="modal" data-target="#trigger_tests">Trigger Tests</a>
                  % endif
                </div>
                <div id="test_status_badge">
                  <i class="spinner fa fa-spinner fa-spin fa-fw"></i>
                </div>
              </div>
              </div>
              % endif
              <div class="mt-3">
                  <div class="h5 d-flex align-items-center font-weight-bold border-bottom">
                      <div class="py-2 text-uppercase font-size-09">Builds</div>
                       <span class="badge badge-secondary badge-pill ml-1">${len(update.builds)}</span>
                      % if request.user and update.from_tag and not update.release.composed_by_bodhi:
                      <span class="badge badge-light badge-pill ml-auto border" title="Builds from the Side Tag: ${update.from_tag}" data-toggle="tooltip"><i class="fa fa-tag pr-1"></i> ${update.from_tag}</span>
                      % endif
                  </div>

              % for build in update.builds:
              <%
              koji_web_url = request.registry.settings.get('koji_web_url').strip('/') + '/'
              build_url = urljoin(koji_web_url, 'search?terms='+build.nvr+'&type=build&match=glob')
              %>
              <div class="pb-1">
                  <div class="row">
                    <div class="col text-muted text-truncate" data-toggle="tooltip" title="${build.nvr}"><a href="${build_url}" target="_blank">
                        ${build.nvr}</a></div>
                  </div>
              </div>
              % endfor

              </div>
              <div class="mt-3">
                  <div class="h5 d-flex align-items-center font-weight-bold border-bottom">
                      <div class="py-2 text-uppercase font-size-09">Settings</div>
                  </div>


              % if update.unstable_karma:
              <div class="pb-1">
                  <div class="row">
                    <div class="col font-weight-bold text-muted">Unstable by Karma</div>
                    <div class="col-xs-auto font-weight-bold">
                          <span class="text-muted font-weight-bold" data-toggle='tooltip' title='The update will be marked as unstable when karma reaches ${update.unstable_karma} '>
                            <i class="fa fa-thumbs-down pr-1"></i>${update.unstable_karma}
                          </span>
                    </div>
                  </div>
              </div>
              % endif

              % if update.autokarma is True and update.stable_karma:
              <div class="pb-1">
                  <div class="row">
                    <div class="col font-weight-bold text-muted">Stable by Karma</div>
                    <div class="col-xs-auto font-weight-bold">
                          <span class="text-muted font-weight-bold" data-toggle='tooltip' title='The update will be automatically pushed to stable when karma reaches ${update.stable_karma}'>
                            <i class="fa fa-thumbs-up pr-1"></i>${update.stable_karma}
                          </span>
                    </div>
                  </div>
              </div>
              % endif

              % if update.autotime is True and update.stable_days:
              <div class="pb-1">
                  <div class="row">
                    <div class="col font-weight-bold text-muted">Stable by Time</div>
                    <div class="col-xs-auto font-weight-bold">
                          <span class="text-muted font-weight-bold" data-toggle='tooltip' title='The update will be automatically pushed to stable after being in testing for ${update.stable_days} days'>
                            ${update.stable_days} days
                          </span>
                    </div>
                  </div>
              </div>
              % endif
              </div>
              <div class="mt-3">
                  <div class="h5 d-flex align-items-center font-weight-bold border-bottom">
                      <div class="py-2 text-uppercase font-size-09">Dates</div>
                  </div>
                    <div class="row">
                      <div class="col font-weight-bold text-muted">submitted</div>
                      <div class="col-xs-auto font-weight-bold">
                            <span class="text-muted font-weight-bold" data-toggle='tooltip' title='${(update.date_submitted).strftime("%Y-%m-%d %H:%M:%S")} (UTC)'>
                                ${self.util.age(update.date_submitted)}
                            </span>
                      </div>
                    </div>

                    % if update.date_testing:
                    <div class="row">
                      <div class="col font-weight-bold text-muted">in testing</div>
                        <div class="col-xs-auto font-weight-bold">
                          <span class="text-muted font-weight-bold" data-toggle='tooltip' title='${(update.date_testing).strftime("%Y-%m-%d %H:%M:%S")} (UTC)'>
                            ${self.util.age(update.date_testing)}
                          </span>
                        </div>
                      </div>
                    % endif

                    % if update.date_stable:
                    <div class="row">
                      <div class="col font-weight-bold text-muted">in stable</div>
                        <div class="col-xs-auto font-weight-bold">
                          <span class="text-muted font-weight-bold" data-toggle='tooltip' title='${(update.date_stable).strftime("%Y-%m-%d %H:%M:%S")} (UTC)'>
                            ${self.util.age(update.date_stable)}
                          </span>
                        </div>
                      </div>
                    % endif

                    % if update.days_to_stable and update.status.value == 'testing':
                    <div class="row">
                      <div class="col font-weight-bold text-muted">days to stable</div>
                        <div class="col-xs-auto font-weight-bold">
                          <span class="text-muted font-weight-bold">
                            ${str(update.days_to_stable)}
                          </span>
                        </div>
                      </div>
                    % endif

                    % if update.date_modified:
                    <div class="row">
                      <div class="col font-weight-bold text-muted">modified</div>
                        <div class="col-xs-auto font-weight-bold">
                          <span data-toggle='tooltip' title='${(update.date_modified).strftime("%Y-%m-%d %H:%M:%S")} (UTC)' class="text-muted font-weight-bold">
                              ${self.util.age(update.date_modified)}
                          </span>
                        </div>
                      </div>
                    % endif

                    % if update.date_approved:
                    <div class="row">
                      <div class="col font-weight-bold text-muted">approved</div>
                        <div class="col-xs-auto font-weight-bold">
                          <span data-toggle='tooltip' title='${(update.date_approved).strftime("%Y-%m-%d %H:%M:%S")} (UTC)' class="text-muted font-weight-bold">
                              ${self.util.age(update.date_approved)}
                          </span>
                        </div>
                      </div>
                    % endif
              </div>
        </div>
      </div>
    </div>

    % if update.bugs:
    <div class="tab-pane" id="bugs" role="tabpanel">
      <div class="list-group my-3">
        % for bug in update.bugs:
        <div class="list-group-item">
          <div class="row align-self-center">
            <div class="col font-weight-bold">${self.util.bug_link(bug) | n}</div>
            <div class="col-xs-auto pl-3 font-weight-bold">${self.fragments.karma(update.get_bug_karma(bug)[0], show_digit=True, zero_thumbsup=False)}</div>
            <div class="col-xs-auto pl-3 font-weight-bold">${self.fragments.karma(update.get_bug_karma(bug)[1], show_digit=True, zero_thumbsup=True)}</div>
          </div>
        </div>
        % endfor
      </div>
    </div>
    % endif

    <div class="tab-pane" id="packages" role="tabpanel">
      <table class="table">
        % for build in update.builds:
        <tr class="media">
          <td>
            <%
              koji_web_url = request.registry.settings.get('koji_web_url').strip('/') + '/'
              build_url = urljoin(koji_web_url, 'search?terms='+build.nvr+'&type=build&match=glob')
            %>
            <a href="${build_url}" target="_blank">
                ${build.nvr}</a>
          </td>
          <td class="float-right">
            % if build.signed:
              <span class="fa fa-key text-muted" aria-hidden="true" data-toggle="tooltip" data-placement="top" title="Build signed"></span>
            % endif
          </td>
          <td class="float-right">
            <a href='${request.route_url("updates_rss") + "?packages=" + build.package.name}'>
              <span class="fa fa-rss" data-toggle="tooltip" data-placement="top" title="RSS feed for new Bodhi updates containing ${build.package.name}"></span>
            </a>
            <a href='${request.route_url("updates") + "?packages=" + build.package.name}'>
              <span class="fa fa-list" data-toggle="tooltip" data-placement="top" title="Show other Bodhi updates for ${build.package.name}"></span>
            </a>
            % if can_edit:
            % if build.override:
            <a href="${request.route_url('override', nvr=build.nvr)}">
              <span class="fa fa-pencil" data-toggle="tooltip" data-placement="top" title="Edit the buildroot override for ${build.nvr}"/>
            </a>
            % else:
            <a href='${request.route_url("new_override")}?nvr=${build.nvr}'>
              <span class="fa fa-plus" data-toggle="tooltip" data-placement="top" title="Create a buildroot override for ${build.nvr}"/>
            </a>
            % endif
            % endif
          </td>
        </tr>
        % endfor
      </table>
    </div>

    <div class="tab-pane" id="automatedtests" role="tabpanel">
      <div id="resultsdb">
      <h3>Automated Test Results</h3>
      <i class="fa spinner fa-spinner fa-spin fa-fw"></i>
      </div>
    </div>

    % if update.test_cases:
    <div class="tab-pane" id="tests" role="tabpanel">
    <h3>Test Cases</h3>
    <table class="table">
      <colgroup class='strip' span="1"></colgroup>
      <colgroup class='strip' span="1"></colgroup>
      <colgroup span="1"></colgroup>
      <thead>
        <tr>
          <th><span data-toggle="tooltip" data-placement="top" title="FAIL - Does not fix the bug or pass the test case." class="fa fa-times-circle-o"></span></th>
          <th><span data-toggle="tooltip" data-placement="top" title="PASS - Fixes the bug or passes the test case." class="fa fa-check-circle-o"></span></th>
          <th></th>
        </tr>
      </thead>
      % for test in update.full_test_cases:
      <tr>
        <td>${self.fragments.karma(update.get_testcase_karma(test)[0], show_digit=True, zero_thumbsup=False)}</td>
        <td>${self.fragments.karma(update.get_testcase_karma(test)[1], show_digit=True, zero_thumbsup=True)}</td>
        <td>${self.util.testcase_link(test) | n}</td>
      </tr>
      % endfor
    </table>
  </div>
    % endif
  </div>
</div> <!-- end container -->

% if self.util.can_waive_test_results(update):
<div class="modal fade" id="waive_test_results" tabindex="-1" role="dialog" aria-labelledby="waiveModalLabel" aria-hidden="true">
  <form>
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h3 class="modal-title" id="waiveModalLabel">Waive All Test Results</h3>
      </div>
      <div class="modal-body">
          <div class="row">
            <div class="col-sm-offset-2 col-sm-10">
              <p>Submitting this will waive the following test results blocking this update:</p>
              <ul id="failed_requirements" class="list-group list-group-flush"></ul>
            </div>
          </div>
          <div class="form-group row">
            <label for="waive_comment" class="col-sm-2 col-form-label">Comment</label>
            <div class="col-sm-10">
              <textarea class="form-control" id="waive_comment" name="waive_comment" placeholder="A reason for the waiver..." required></textarea>
            </div>
          </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
        <button type="submit" class="btn btn-primary">Waive</button>
      </div>
    </div>
  </div>
  </form>
</div>
% endif

% if self.util.can_trigger_tests(update):
<div class="modal fade" id="trigger_tests" tabindex="-1" role="dialog" aria-labelledby="waiveModalLabel" aria-hidden="true">
  <form>
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h3 class="modal-title" id="waiveModalLabel">Trigger Tests</h3>
      </div>
      <div class="modal-body">
          <div class="row">
            <div class="col-sm-offset-2 col-sm-10">
              <p>Submitting this will the tests again.</p>
            </div>
          </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
        <button type="submit" class="btn btn-primary">Trigger new test run</button>
      </div>
    </div>
  </div>
  </form>
</div>
% endif


<%block name="javascript">
${parent.javascript()}
<script src="${request.static_url('bodhi:server/static/vendor/messenger/js/messenger.min.js')}"></script>
<script src="${request.static_url('bodhi:server/static/vendor/messenger/js/messenger-theme-flat.js')}"></script>
<script src="${request.static_url('bodhi:server/static/js/forms.js')}"></script>
<script src="${request.static_url('bodhi:server/static/js/comment_form.js')}"></script>
<script src="${request.static_url('bodhi:server/static/vendor/moment/moment.min.js')}"></script>
<script>
  $(document).ready(function() {
    // Some handy lookups that map taskotron states to bootstrap CSS classes.
    var classes = {
      PASSED: 'success',
      INFO: 'info',
      FAILED: 'danger',
      NEEDS_INSPECTION: 'warning',
      ABORTED: 'warning',
      CRASHED: 'warning',
      ABSENT: 'danger',
    }
    var icons = {
      PASSED: 'check-circle',
      INFO: 'info-circle',
      FAILED: 'minus-circle',
      NEEDS_INSPECTION: 'exclamation-circle',
      ABORTED: 'trash',
      CRASHED: 'fire', // no joke.
      ABSENT: 'question-circle',
    }

    var update = '${update.alias}';
    var builds = ${update.builds_json | n};

    // These are the required taskotron tests
    var requirements = ${update.requirements_json | h};
    // These are the known waivers of failed testcases.
    var waivers = {};
    // show the Greenwave decision
    var greenwave_api_url = '${request.registry.settings["greenwave_api_url"]}';
    var missing_tests = {};

    // handle Greenwave decision
    var handle_unsatisfied_requirements = function(data){
        $.each(data['unsatisfied_requirements'], function(i, requirement) {
            if (requirement.type == 'test-result-missing') {
                if (missing_tests[requirement.subject_identifier] === undefined)
                    missing_tests[requirement.subject_identifier] = [];
                missing_tests[requirement.subject_identifier].push(requirement);
            }
            // the user may have already specified this in the required taskotron tests
            if ($.inArray(requirement.testcase, requirements) == -1) {
                requirements.push(requirement.testcase);
            }
            $('#failed_requirements').append('<li class="list-group-item">' + requirement.testcase + '</li>');

            // there is at least one unsatisfied requirement, so show the button to be able to waive.
            $('#waive').show();
        });
        % if request.registry.settings.get("test_gating.required") is True:
            if (data['policies_satisfied']) {
              label_class = classes['PASSED'];
              icon_class = icons['PASSED'];
            } else if (missing_tests.length != 0) {
              label_class = classes['ABSENT'];
              icon_class = icons['ABSENT'];
            } else {
              label_class = classes['FAILED'];
              icon_class = icons['FAILED'];
            }

            var html = '<span class="badge badge-' + label_class + '">' +
              '<span class="fa fa-' + icon_class + '">' +
              '</span></span> ';
            html += '<a class="gating-summary notblue" href="#automatedtests">' + data['summary'];
            html += '</a>';
            if (data.waivers.length != 0) {
                 // Create url to waiverdb with waivers for this update
                 var url = '${request.registry.settings["waiverdb_api_url"]}';
                 url += '/waivers'
                 url += '/?product_version=' + data.waivers[0].product_version;
                 url += '&subject_type=' + data.waivers[0].subject_type;
                 url += '&subject_identifier=' + data.waivers[0].subject_identifier;
                 html += '<a class="notblue" target="_blank" href=' + url + '>';
                 html += '<span data-toggle="tooltip" data-placement="top" ' +
                 'title="Some tests failures were waived." ' +
                 'class="fa fa-asterisk">' +
                 '</span>';
                 html += '</a>';
            }
            $('#test_status_badge').append(html);
            $('#resultsdb h3').after(html);

            $('.gating-summary').click(function(e){
              e.preventDefault();
              $('.nav-tabs a[href="#automatedtests"]').tab('show');
            });
        % endif
    };

    var get_greenwave_information = function(request, after_success) {
        request.verbose = true;
        $.ajax({
            url: greenwave_api_url + '/decision',
            type: 'POST',
            contentType: 'application/json',
            data: JSON.stringify(request),
            success: function(data) {
                $.each(data.waivers, function(i, waiver) {
                  if (!(waiver.testcase in waivers)) { waivers[waiver.testcase] = []; }
                  waivers[waiver.testcase].push(waiver);
                });
                handle_unsatisfied_requirements(data);
                handle_results(data.results, request.subject);
                after_success();
            },
            error: function (jqxhr, status, error) {
               finish();
               $('#resultsdb h3').after(
                  '<h4 class="text-danger">Failed to talk to Greenwave.</h4>');
               $('#test_status_badge').append(
                  '<span class="text-danger">Failed to talk to Greenwave.</span>');
            },
        });
    };

    var make_row = function(outcome, testcase, note, arch, time, url, flavor) {
      var icon = '<span data-toggle="tooltip" data-placement="top" ' +
        'title="' + outcome + '" ' +
        'class="fa fa-' + icons[outcome] + ' text-' + classes[outcome] + '">'+
        '</span>';

      var required = '';
      if (testcase in waivers) {
        var reason = 'Waived by ';
        var comments = [];
        for (let w of waivers[testcase]) {
          waiver_details = "@" + w.username + ": '" + w.comment.replace("'", "&#39;") + "'"
          comments.push(waiver_details);
        }
	reason += comments.join(", ")
        required = '<span style="white-space:pre-line;" data-toggle="tooltip" data-placement="top" ' +
          'title="' + reason + '" ' +
          'class="fa fa-thumbs-up">' +
          '</span>';
      } else if ($.inArray(testcase, requirements) != -1) {
        required = '<span data-toggle="tooltip" data-placement="top" ' +
          'title="' + testcase + ' is a required test" ' +
          'class="fa fa-asterisk">' +
          '</span>';
      }

      if (arch != undefined) {
        testcase = testcase + "&nbsp;<span class='badge badge-secondary'>"
          + arch + "</label>";
      }

      if (flavor) {
        testcase = testcase + "&nbsp;<span class='badge badge-secondary'>"
          + flavor + "</label>";
      }

      var age = '';
      if (time != undefined) {
        // The ' Z' tells moment.js to interpret the time as UTC
        // https://github.com/fedora-infra/bodhi/issues/217
        var age = moment(time + ' Z').fromNow();
      }
      if (note == null){
        note = '';
      }
      html = '<tr class="row-automatedtests table-' + classes[outcome];
      if (outcome == 'ABSENT') {
          html += ' absent-automatedtest"';
      } else {
          html += '" style="cursor: pointer;" data-href="' + url + '"';
      }
      html += '>' +
        '<td>' + required + '</td>' +
        '<td>' + icon + '</td>' +
        '<td class="nowrap">' + testcase + '</td>' +
        '<td class="stretch-table-column text-xs-right">' + note + '</td>' +
        '<td class="nowrap">' + age + '</td>' +
        '</tr>';
      return html;
    };

    var handle_results = function(results, subjects) {
      var build_results = {}
      $.each(subjects, function(i, subject) {
        build_results[subject.item] = [];
      });

      // First, prune duplicate results.  For instance, some depcheck runs
      // happen multiple times on an update.  We only (imho) want to display
      // the latest ones for each arch.  So, prune like this:
      var latest = {};
      $.each(results, function(i, result) {
        var testcase = result.testcase.name;
        var scenario = 'no_scenario';
        if (result.data.scenario) {
            scenario = result.data.scenario[0];
        }
        // note: these are actually single-item arrays, though this doesn't
        // seem to break anything
        var arch = result.data.arch;
        var item = result.data.item;
        var submit_time = new Date(result.submit_time);

        var key = [item, testcase, arch, scenario].join('##');
        var last_submit_time = latest[key];
        if (last_submit_time === undefined || last_submit_time < submit_time) {
          latest[key] = submit_time;

          if (item in build_results) {
            build_results[item].push(result);
          } else {
            build_results[item] = [result];
          }
        }
      });

      $.each(build_results, function(buildname, results) {
        $("#resultsdb").append("<h4 class='pt-1'>" + buildname + "</h4>")

        // no results reported
        if (!(buildname in missing_tests) && results.length === 0) {
          $("#resultsdb").append("<p>No results reported for this build.</p>");
          return;
        }

        var table = $("<table class='table table-hover'></table>").appendTo("#resultsdb");

        // show missing tests first
        if (buildname in missing_tests) {
          $.each(missing_tests[buildname], function(i, result) {
            table.append(make_row(
              'ABSENT',
              result.testcase,
              '',
              '',
              ''
            ));
          });
        }

        $.each(results, function(i, result) {
          var scenario = 'no_scenario';
          if (result.data.scenario) {
              scenario = result.data.scenario[0];
          }

          var flavor;
          if (scenario.includes("updates-server")) {
            flavor = "server";
          }
          else if (scenario.includes("updates-workstation")) {
            flavor = "workstation";
          }

          table.append(make_row(
              result.outcome,
              result.testcase.name,
              result.note,
              // note: this is a single-item array
              result.data.arch,
              result.submit_time,
              result.ref_url,
              flavor
          ));
        });
      });
    };

    var update = function() {
      // add the count of tests to the automated tests tab
      $.each(['success', 'info', 'warning', 'danger'], function(i, counter) {
        var count = $('.row-automatedtests.table-' + counter).length;
        if (count > 0) {
          $("#automatedtests-" + counter).text(count).parent().show();
        }
      });

      // Make each cell clickable and awesome except the missing tests
      $('#resultsdb tr').not('.absent-automatedtest').off().click(function(event, row) {
        window.open($(this).attr('data-href'));
      });

      // And, re-do tooltips for newly created spans.
      $('#resultsdb span').tooltip();
    }

    var finish = function() {
      $("#tab-automatedtests .fa-spinner").remove();
      $('#resultsdb .spinner').remove();
      $('#test_status_badge .spinner').remove();
    }


    var request_results = function(url) {
      $.ajax(url, {
        beforeSend: function(xhr) {
          activeResultsAjaxCalls++;
        },
        dataType: 'jsonp',
        cache: false,
        success: receive_resultsdb,
      });
    };

    $("#tab-automatedtests").append(" <span class='fa fa-spinner fa-spin'></span>");

    var request_batches = ${update.greenwave_request_batches_json | n};
    var current_batch = 0;
    var progress = $('#automatedtests-progress');
    var fetch_next_batch = function() {
      update()

      if (current_batch >= request_batches.length) {
        progress.remove()
        finish();
        return;
      }

      var percent = Math.floor(current_batch * 100 / request_batches.length)
      progress.text(percent + '%')

      var request = request_batches[current_batch]
      ++current_batch;

      get_greenwave_information(request, fetch_next_batch);
    };
    fetch_next_batch();
  });
</script>

<script>
$(document).ready(function() {
    var messenger = Messenger({theme: 'flat'});
    var update_id = '${update.alias}';
    $("#edit").attr('href',
        '${request.route_url("update_edit", id=update.alias)}');

    $.each(['testing', 'stable', 'unpush', 'revoke'], function(i, action) {
      $("#updatebuttons #" + action).click(function() {
          if (action == 'unpush') {
              var r = confirm('Are you sure you want to unpush this update?');
              if (r === false) { return; }
          }
          $("#updatebuttons a").addClass('disabled');
          var url = '${request.route_url("update_request", id=update.alias)}';
          $.ajax({
              url: url,
              data: {
                request: action,
                csrf_token: "${request.session.get_csrf_token()}",
              },
              method: 'POST',
              dataType: 'json',
              success: function(response) {
                // Just reload the page if all went well..
                location.reload();
              },
              error: function(response) {
                $("#updatebuttons a").removeClass('disabled');
                $.each(response.responseJSON.errors, function(i, error) {
                    msg = messenger.post({
                      message: error.description,
                      type: "error",
                      hideAfter: false,
                      showCloseButton: true,
                    });
                });
              },
          });
      });
    });

% if self.util.can_waive_test_results(update):
    // handle for waiving test results.
    // set focus on the comment textarea when opening the modal.
    $("#waive_test_results").on('shown.bs.modal', function () {
        $('#waive_comment').trigger('focus')
    });
    $("#waive_test_results").submit(function(evt) {
      evt.preventDefault();
      var comment = $('#waive_test_results [name=waive_comment]').val();
      var url = '${request.route_url("update_waive_test_results", id=update.alias)}';
      var $this = $(this);
      $.ajax({
          url: url,
          data: {
            comment: comment,
            csrf_token: "${request.session.get_csrf_token()}",
          },
          method: 'POST',
          dataType: 'json',
          success: function(response) {
            // Just reload the page to refresh the test gating status.
            location.reload();
          },
          error: function(response) {
            $this.modal('hide');
            $.each(response.responseJSON.errors, function(i, error) {
                msg = messenger.post({
                  message: error.description,
                  type: "error",
                  hideAfter: false,
                  showCloseButton: true,
                });
            });
          },
      });
    });
% endif

% if self.util.can_trigger_tests(update):
    // handle for triggering of tests.
    $("#trigger_tests").submit(function(evt) {
      evt.preventDefault();
      var url = '${request.route_url("update_trigger_tests", id=update.alias)}';
      var $this = $(this);
      $.ajax({
        url: url,
        data: {
          csrf_token: "${request.session.get_csrf_token()}",
        },
        method: 'POST',
        dataType: 'json',
        success: function(response) {
          // Just reload the page to refresh the test gating status.
          location.reload();
        },
        error: function(response) {
          $this.modal('hide');
          $.each(response.responseJSON.errors, function(i, error) {
              msg = messenger.post({
                message: error.description,
                type: "error",
                hideAfter: false,
                showCloseButton: true,
              });
          });
        },
      });
    });
% endif
});
</script>

<script>
$(document).ready(function(){
    var button = document.getElementById('copybutton')

    if (button == null) {
        return;
    }

    button.addEventListener('click', function(event) {
        if (document.selection) { 
            document.selection.empty();
            var range = document.body.createTextRange();
            range.moveToElementText(document.getElementById('commandtext'));
            range.select().createTextRange();
            try {
                document.execCommand('copy');
            } catch (err) {
                console.log('Oops, unable to copy');
            }
        } else if (window.getSelection) {
            if (window.getSelection().empty) {  // Chrome
                window.getSelection().empty();
            } else if (window.getSelection().removeAllRanges) {  // Firefox
                window.getSelection().removeAllRanges();
            }
            var range = document.createRange();
            range.selectNode(document.getElementById('commandtext'));
            window.getSelection().addRange(range);
            try {
                document.execCommand('copy');
            } catch (err) {
                console.log('Oops, unable to copy');
            }
        }
    });
});
</script>
</%block>
