<?xml version="1.0" encoding="utf-8"?>
<odoo>
  <data>
    <template id="runbot.build">
      <t t-call='runbot.layout'>
        <t t-set="nav_form">
          <form class="form-inline">
            <div class="btn-group">
              <t t-call="runbot.build_button">
                <t t-set="bu" t-value="build"/>
                <t t-set="klass" t-value="''"/>
                <t t-set="show_commit_button" t-value="True"/>
              </t>
            </div>
          </form>
        </t>
        <div class="row g-0">
          <div class="col-md-12">
            <t t-set="batches" t-value="build.top_parent.with_context(active_test=False).slot_ids.mapped('batch_id')"/>
            <t t-set="bundles" t-value="batches.mapped('bundle_id')"/>

            <t t-if="from_batch" t-set="unique_batch" t-value="from_batch"/>
            <t t-if="from_batch" t-set="unique_bundle" t-value="from_batch.bundle_id"/>
            <t t-if="not unique_batch and len(batches) == 1" t-set="unique_batch" t-value="batches"/>
            <t t-if="not unique_bundle and len(bundles) == 1" t-set="unique_bundle" t-value="bundles"/>

            <!-- Breadcrumbs & Previous/Next-->
            <nav aria-label="breadcrumb" class="d-flex justify-content-between align-items-center">
              <ol class="breadcrumb mb-0">
                <li t-attf-class="breadcrumb-item">
                  <a t-attf-href="/runbot/{{build.params_id.project_id.id}}">
                    <t t-out="build.params_id.project_id.name"/>
                  </a>
                </li>
                <li t-if="unique_bundle" t-attf-class="breadcrumb-item">
                  <a t-att-href="unique_bundle._url()">
                    <t t-out="unique_bundle.name"/>
                  </a>
                </li>
                <li t-if="unique_batch" t-attf-class="breadcrumb-item">
                  <a t-att-href="unique_batch._url()">
                    batch-<t t-out="unique_batch.id"/> (<t t-out="build.params_id.trigger_id.name"/>)
                  </a>
                </li>
                <li t-foreach="build.ancestors" t-as="ancestor" t-attf-class="breadcrumb-item{{' active' if ancestor == build else ''}}">
                  <a t-att-href="ancestor.build_url">
                    <t t-out="ancestor.description or ancestor.config_id.name"/>
                  </a>
                </li>
              </ol>
              <span class="btn-group pe-3">
                <a t-att-href="prev_ko.build_url" role="button" t-attf-title="Previous ko {{prev_ko.display_name}}"
                   t-attf-class="{{'' if prev_ko else 'disabled '}}btn btn-default fa fa-angle-double-left"></a>
                <a t-att-href="prev_bu.build_url" role="button" t-attf-title="Previous {{prev_bu.display_name}}"
                   t-attf-class="{{'' if prev_bu else 'disabled '}}btn btn-default fa fa-chevron-left"></a>
                <a t-att-href="next_bu.build_url" role="button" t-attf-title="Next {{next_bu.display_name}}"
                   t-attf-class="{{'' if next_bu else 'disabled '}}btn btn-default fa fa-chevron-right"></a>
                <a t-att-href="next_ko.build_url" role="button" t-attf-title="Next ko {{next_ko.display_name}}"
                   t-attf-class="{{'' if next_ko else 'disabled '}}btn btn-default fa fa-angle-double-right"></a>
              </span>
            </nav>
          </div>
          <!-- Build details-->
          <t t-set="rowclass">
            <t t-call="runbot.build_class">
              <t t-set="build" t-value="build"/>
            </t>
          </t>
          <div t-attf-class="bg-{{rowclass.strip()}}-subtle {{'col-md-6' if build.children_ids else 'col-md-12'}}">
            <div class="build_details">
              <!-- Batch/bundles links-->
              <t t-if="len(bundles) > 1">
                This build is referenced in <t t-out="len(bundles)"/> bundles
                <ul>
                  <li t-foreach="bundles" t-as="bundle" ><a t-out="bundle.name" t-attf-href="/runbot/bundle/{{bundle.id}}"/></li>
                </ul>
              </t>
              <t t-if="len(batches) > 1">
                <b>First apparition:</b> <a t-out="batches[0].bundle_id.name" t-attf-href="/runbot/batch/{{batches[0].id}}"/><br/>
                <b>Last apparition:</b> <a t-out="batches[-1].bundle_id.name" t-attf-href="/runbot/batch/{{batches[-1].id}}"/><br/>
              </t>
              <!-- Parent -->
              <div t-if="build.parent_id and build.orphan_result">
                <i class="fa fa-chain-broken" title="Build result ignored for parent" />
                &amp;nbsp;Orphaned build, the result does not affect parent build result
              </div>

              <t t-if="build.description">
                <b>Description:</b>
                <t t-out="build.md_description"/>
                <br/>
              </t>

              <!-- Commits -->
              <t t-foreach="build.params_id.sudo().commit_link_ids" t-as="build_commit">
                <b>Commit:</b>
                <a t-attf-href="/runbot/commit/{{build_commit.commit_id.id}}">
                  <t t-out="build_commit.commit_id.dname"/>
                </a>
                &amp;nbsp;
                <a t-att-href="'https://%s/commit/%s' % (build_commit.branch_id.remote_id.base_url, build_commit.commit_id.name)" title="View Commit on Github"><i class="fa fa-github"/></a>
                <t t-if="build_commit.match_type in ('default', 'pr_target', 'prefix') ">
                  from base branch
                  <br/>
                </t>
                <div t-else="" class="ms-3">
                  <b>Subject:</b>
                  <t t-out="build_commit.commit_id.subject"/>
                  <br/>
                  <b>Author:</b>
                  <t t-out="build_commit.commit_id.author"/>
                  <br/>
                  <b>Committer:</b>
                  <t t-out="build_commit.commit_id.committer"/>
                  <br/>
                </div>
              </t>
              <b>Version:</b>
              <t t-out="build.params_id.version_id.name"/>
              <br/>
              <b>Config:</b>
              <t t-out="build.params_id.config_id.name"/>
              <br/>
              <t t-if='more'>
                <b>Trigger:</b>
                <t t-out="build.params_id.trigger_id.name"/>
                <br/>
                <b>Config data:</b>
                <t t-out="build.params_id.config_data.dict"/>
                <br/>
                <b>Modules:</b>
                <t t-out="build.params_id.modules"/>
                <br/>
                <b>Extra params:</b>
                <t t-out="build.params_id.extra_params"/>
                <br/>
                <t t-if="build.params_id.builds_reference_ids">
                  <b>Reference builds:</b>
                  <div t-foreach="build.params_id.builds_reference_ids" t-as="reference">
                    <a t-attf-href="/runbot/build/{{reference.id}}"><t t-esc="reference.id"/></a> - <em t-out="reference.params_id.version_id.name"/>
                  </div>
                </t>
                <t t-if="len(build.params_id.build_ids) > 1">
                  <b>Similar builds:</b>
                  <t t-foreach="build.params_id.build_ids" t-as="simbuild">
                    <a t-if="simbuild.id != build.id" t-attf-href="/runbot/build/#{simbuild.id}">
                      <span
                        t-attf-class="badge text-bg-{{simbuild._get_color_class()}}"
                        t-out="simbuild.id"/>
                    </a>
                  </t>
                  <br/>
                </t>
                <b>Host:</b>
                <t t-out="build.host"/>
              </t>
              <div>
                <b title="Execution time of this build, without child time">
                  Build time:
                </b>
                <t t-att-tile='build.build_time' t-out="s2human(build.build_time)"/>
                <i t-if='more'>(<t t-out="build.build_time"/>s)</i>
              </div>
              <div>
                <b title='Time from creation to finish (queue time + completion time)'>
                  Wait time:
                </b>
                <t t-att-tile='build.wait_time' t-out="s2human(build.wait_time)"/>
                <i t-if='more'>(<t t-out="build.wait_time"/>s)</i>
              </div>
              <div>
                <b title='Total time '>
                  Load time:
                </b>
                <t t-att-tile='build.load_time' t-out="s2human(build.load_time)"/>
                <i t-if='more'>(<t t-out="build.load_time"/>s)</i>
              </div>
              <div>
                <t t-if="build.stat_ids">
                  <b>Stats:</b>
                    <a t-attf-href="/runbot/build/stats/{{build.id}}">Build <t t-out="build.id"/></a>
                  <br/>
                </t>
              </div>
            </div>
          </div>
          <div class="col-md-6" t-if="build.children_ids">
            Children:
            <table class="table table-condensed">
              <t t-foreach="build.children_ids.sorted('id')" t-as="child">
                <t t-set="rowclass">
                  <t t-call="runbot.build_class">
                    <t t-set="build" t-value="child"/>
                  </t>
                </t>
                <tr t-attf-class="bg-{{rowclass.strip()}}-subtle{{' line-through' if child.orphan_result else ''}}">
                  <td>
                    <a t-attf-href="/runbot/{{'batch/%s/' % from_batch.id if from_batch else ''}}build/{{child.id}}">
                      Build
                      <t t-out="child.id"/>
                    </a>
                    <t t-if="child.description">
                      <t t-out="child.md_description" />
                    </t>
                    <t t-else="">
                      with config
                      <t t-out="child.params_id.config_id.name"/>
                    </t>
                    <a groups="runbot.group_build_config_user" t-attf-href="/web#id={{child.params_id.config_id.id}}&amp;view_type=form&amp;model=runbot.build.config">...</a>
                    <t t-if="child.orphan_result">
                      <i class="fa fa-chain-broken" title="Build result ignored for parent" />
                    </t>
                    <t t-if="child.job">
                      Running step:
                      <t t-out="child.job"/>
                    </t>
                    <t t-if="child.global_state in ['testing', 'waiting']">
                      <i class="fa fa-spinner fa-spin"/>
                      <t t-out="child.global_state"/>
                    </t>
                  </td>
                  <td>
                    <span t-attf-class="badge text-bg-info" t-out="s2human(child.build_time)"/>
                  </td>
                  <td>
                    <t t-call="runbot.build_button">
                      <t t-set="bu" t-value="child"/>
                      <t t-set="klass" t-value="'btn-group-ssm'"/>
                    </t>

                  </td>
                </tr>
              </t>
            </table>
          </div>
          <t t-set="nb_subbuild" t-value="len(build.children_ids)"/>
          <div class="col-md-12">
            <table class="table table-condensed">
              <tr>
                <th>Date</th>
                <th>Level</th>
                <th>Type</th>
                <th>Message</th>
              </tr>

              <t t-set="commit_link_per_name" t-value="{commit_link.commit_id.repo_id.name:commit_link for commit_link in build.params_id.commit_link_ids}"/>
              <t t-foreach="build.sudo().log_ids" t-as="l">
                <t t-set="subbuild" t-value="(([child for child in build.children_ids if child.id == int(l.path)] if l.type == 'subbuild' else False) or [build.browse()])[0]"/>
                <t t-set="logclass" t-value="dict(CRITICAL='danger', ERROR='danger', WARNING='warning', OK='success', SEPARATOR='separator').get(l.level)"/>
                <tr t-att-class="'separator' if logclass == 'separator' else ''" t-att-title="l.active_step_id.description or ''">
                  <td style="white-space: nowrap; width:1%;">
                    <t t-out="l.create_date.strftime('%Y-%m-%d %H:%M:%S')"/>
                  </td>
                  <td style="white-space: nowrap; width:1%;">
                    <b t-if="l.level != 'SEPARATOR' and l.type not in ['link', 'markdown']" t-out="l.level"/>
                  </td>
                  <td style="white-space: nowrap; width:1%;">
                    <t t-if="l.level != 'SEPARATOR' and l.type not in ['link', 'markdown']" t-out="l.type"/>
                  </td>
                  <t t-set="message_class" t-value="''"/>
                  <t t-if="subbuild" t-set="message_class">
                    <t t-call="runbot.build_class">
                      <t t-set="build" t-value="subbuild"/>
                    </t>
                  </t>
                  <td t-attf-class="bg-{{message_class.strip() or logclass}}-subtle">
                    <t t-if="l.type not in ('runbot', 'link', 'markdown')">
                      <t t-if="l.type == 'subbuild'">
                        <a t-attf-href="/runbot/build/{{l.path}}">
                          Build #
                          <t t-out="l.path"/>
                        </a>
                      </t>
                      <t t-else="">
                        <t t-set="repo_name" t-value="l.path.replace('/data/build/', '').split('/')[0] "/>
                        <t t-set="href" t-value=""/>
                        <t t-if="repo_name in commit_link_per_name">
                          <t t-set="repo_base_url" t-value="commit_link_per_name[repo_name].branch_id.remote_id.base_url if repo_name in commit_link_per_name else ''"/>
                          <t t-set="commit_hash" t-value="commit_link_per_name[repo_name].commit_id.name if repo_name in commit_link_per_name else ''"/>
                          <t t-set="path" t-value="l.path.replace('/data/build/%s/' % repo_name, '')"/>
                          <t t-set="href" t-value="'https://%s/blob/%s/%s#L%s' % (repo_base_url, commit_hash, path, l.line)"/>
                        </t>
                        <a t-att-href="href" t-attf-title="Func: {{l.func}}"><t t-out="l.name"/>:<t t-out="l.line"/></a>
                      </t>
                    </t>
                    <!-- DEPRECATED: Will be removed once no ir.logging is concerned. -->
                    <span class="log_message" t-if="l.type == 'link' and len(l.message.split('$$')) == 3">
                      <t t-set="message" t-value="l.message.split('$$')"/>
                      <t t-if="message[1].startswith('fa-')">
                        <t t-out="message[0]"/>
                        <a t-attf-href="{{l.path}}">
                          <i t-attf-class="fa {{message[1]}}"/>
                        </a>
                        <t t-out="message[2]"/>
                      </t>
                      <t t-else="">
                        <t t-out="message[0]"/>
                        <a t-attf-href="{{l.path}}">
                          <t t-out="message[1]"/>
                        </a>
                        <t t-out="message[2]"/>
                      </t>
                    </span>
                    <span class="log_message" t-elif="l.type == 'markdown'" t-out="l._markdown()"/>
                    <span class="log_message" t-else="">
                      <t t-if="'\n' not in l.message" t-out="l.message"/>
                      <pre t-if="'\n' in l.message" style="margin:0;padding:0; border: none;"><t t-out="l.message"/></pre>
                    </span>
                  </td>
                  <td t-attf-class="bg-{{message_class.strip() or logclass}}-subtle">
                    <t t-if="l.level in ('CRITICAL', 'ERROR', 'WARNING') and not l.with_context(active_test=False).error_content_id">
                      <small>
                        <a groups="runbot.group_runbot_5admin" t-attf-href="/runbot/parse_log/{{l.id}}" class="sm" title="Parse this log line to follow this error.">
                          <i t-attf-class="fa fa-magic"/>
                        </a>
                      </small>
                    </t>
                  </td>
                </tr>
                <t t-if="l.error_content_id">
                  <t t-set="error_content" t-value="l.error_content_id"/>
                  <t t-set="error" t-value="error_content.error_id"/>
                  <tr>
                    <td/><td/><td/>
                    <td t-attf-class="bg-{{'info' if error.active else 'success'}}-subtle" colspan="2">
                      This error is already <em t-attf-title="{{'Was detected by runbot in nightly builds.' if error.active else 'Either the error is not properly fixed or the branch does not contain the fix.'}}"><t t-out="'known' if error.active else 'fixed'"/></em>.
                      <!--a groups="runbot.group_user" t-attf-href="/web#id={{error_content.id}}&amp;view_type=form&amp;model=runbot.build.error.content&amp;menu_id={{env['ir.model.data']._xmlid_to_res_id('runbot.runbot_menu_root')}}" title="View in Backend" target="_blank">
                        <i t-attf-class="fa fa-search"/>
                      </a-->
                      <a groups="runbot.group_user" t-attf-href="/web#id={{error.id}}&amp;view_type=form&amp;model=runbot.build.error&amp;menu_id={{env['ir.model.data']._xmlid_to_res_id('runbot.runbot_menu_root')}}" title="View in Backend" target="_blank">
                        <i t-attf-class="fa fa-list"/>
                      </a>
                      <span t-if="error.responsible and (env.user.has_group('runbot.group_runbot_error_manager') or error.responsible.id == uid)">(<i t-out="error.responsible.name"/>)</span>
                    </td>
                  </tr>
                </t>
              </t>
            </table>
          </div>
        </div>
      </t>
    </template>
    <template id="runbot.build_search">
      <t t-call='runbot.layout'>
        <div class="row g-0">
          <div class="col-md-12">
            <table class="table table-condensed">
              <t t-foreach="builds" t-as="build">
                <t t-set="rowclass">
                  <t t-call="runbot.build_class">
                    <t t-set="build" t-value="build"/>
                  </t>
                </t>
                <tr t-attf-class="bg-{{rowclass.strip()}}-subtle{{' line-through' if build.orphan_result else ''}}">
                  <td>
                      <t t-out="build.create_date"/>
                  </td>
                  <td>
                    <a t-attf-href="/runbot/{{'batch/%s/' % from_batch.id if from_batch else ''}}build/{{build.id}}">
                      <t t-out="build.id"/>
                    </a>
                  </td>
                  <td>
                    <t t-if="build.description">
                      <t t-out="build.md_description" />
                    </t>
                  </td>
                  <td>
                    <t t-if="build.global_state in ['testing', 'waiting']">
                      <i class="fa fa-spinner fa-spin"/>
                      <t t-out="build.global_state"/>
                    </t>
                  </td>
                  <td>
                    <span t-out="build.params_id.config_id.name"/>
                  </td>
                  <td>
                    <span t-out="build.params_id.version_id.name"/>
                  </td>
                  <td>
                    <span t-out="s2human(build.build_time)"/>
                  </td>
                  <td>
                    <t t-call="runbot.build_button">
                      <t t-set="bu" t-value="build"/>
                      <t t-set="klass" t-value="'btn-group-ssm'"/>
                    </t>
                  </td>
                  <td>
                    <t t-set="commits" t-value="build.params_id.commit_link_ids.commit_id.sorted(key=lambda c: c.repo_id.id)"/>
                    <t t-if="build_index+1 &lt; len(builds)" t-set="previous_commits" t-value="list(builds[build_index+1].params_id.commit_link_ids.commit_id.sorted(key=lambda c: c.repo_id.id))"/>
                    <t t-else="" t-set="previous_commits" t-value="[]"/>
                    <t t-foreach="zip(previous_commits, commits)" t-as="compare">
                      <t t-set="previous_commit" t-value="compare[0]"/>
                      <t t-set="commit" t-value="compare[1]"/>
                      <a t-attf-href="https://{{commit.repo_id.main_remote_id.base_url}}/compare/{{previous_commit.name}}..{{commit.name}}" t-att-title="commit.repo_id.name">
                        <i class="fa fa-plus"/>
                      </a>
                    </t>
                  </td>
                </tr>
              </t>
            </table>
          </div>
        </div>
      </t>
    </template>
  </data>
</odoo>
