/**
 * @module module/verfiers-detail-sk
 * @description <h2><code>verifiers-detail-sk</code></h2>
 *
 * Displays the details of all verifiers that have run for a
 * change+patchset.
 *
 * @attr {number} change_id - The change ID of the Gerrit change.
 *
 * @attr {number} patchset_id - The patchset ID of the Gerrit change.
 *
 */

import { define } from '../../../elements-sk/modules/define';
import { html, TemplateResult } from 'lit-html';
import { upgradeProperty } from '../../../elements-sk/modules/upgradeProperty';
import { diffDate } from '../../../infra-sk/modules/human';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';

import '../../../elements-sk/modules/error-toast-sk';
import '../../../elements-sk/modules/icons/folder-icon-sk';
import '../../../elements-sk/modules/icons/help-icon-sk';
import '../../../elements-sk/modules/icons/home-icon-sk';
import '../../../elements-sk/modules/spinner-sk';

import '../../../infra-sk/modules/app-sk';
import '../../../infra-sk/modules/login-sk';
import '../../../infra-sk/modules/theme-chooser-sk';
import { escapeAndLinkify } from '../../../infra-sk/modules/linkify';

import { doImpl } from '../skcq';
import {
  GetChangeAttemptsRequest, GetChangeAttemptsResponse, ChangeAttempts, ChangeAttempt, VerifierState,
} from '../json';

const VerifierStateToClassName: Record<VerifierState, string> = {
  SUCCESSFUL: 'success',
  WAITING: 'waiting',
  ABORTED: 'aborted',
  FAILURE: 'failed',
};

export class VerifiersDetailSk extends ElementSk {
  noData: boolean = true;

  updatingData: boolean= true;

  changeAttempts: (ChangeAttempts|null) = null;

  constructor() {
    super(VerifiersDetailSk.template);
  }

  private static template = (el: VerifiersDetailSk) => html`
  <spinner-sk ?active=${el.updatingData}></spinner-sk>
  <div ?hidden=${el.noData}>
    <h3>SkCQ attempts for <a href="http://skia-review.googlesource.com/c/${el.changeID}/${el.patchsetID}" target=_blank>${el.changeID}/${el.patchsetID}</a></h3>
    ${el.displayAttempts()}
  </div>
  ${el.displayNotFoundMsg(el.noData, el.updatingData)}
`;

  connectedCallback(): void {
    super.connectedCallback();
    this.fetchAttempts();
    this._render();
  }

  disconnectedCallback(): void {
    super.disconnectedCallback();
  }

  /** @prop change_id The Change ID of the Gerrit change. */
  get changeID(): number {
    return +this.getAttribute('change_id')!;
  }

  /** @prop patchset_id The Patchset ID of the Gerrit change. */
  get patchsetID(): number {
    return +this.getAttribute('patchset_id')!;
  }

  private displayNotFoundMsg(hidden: boolean, updatingData: boolean): TemplateResult {
    if (hidden && !updatingData) {
      return html`<h3>No data available for <a href="http://skia-review.googlesource.com/c/${this.changeID}/${this.patchsetID}" target=_blank>${this.changeID}/${this.patchsetID}</a></h3>`;
    }
    return html``;
  }

  private displayAttempts(): TemplateResult[] {
    if (!this.changeAttempts || !this.changeAttempts!.attempts) {
      return [];
    }
    return this.changeAttempts!.attempts.reverse().map((attempt, index) => html`
    <span class="attempt-section ${this.getStateClass(attempt!.overall_status)}">
      <table class="attempt-table">
        <tr>
          <th width=33%>
            Attempt #${this.changeAttempts!.attempts!.length - index} ${this.getDryRunText(attempt!)}
          </th>
          <th width=33%>
            ${attempt?.overall_status}
          </th>
          <th width=33%>
            Total duration: ${this.getTotalDurationText(attempt!)}
          </th>
        </tr>
      </table>
      <br/>
      <b>Start time</b> ${new Date(attempt!.start_ts * 1000).toLocaleString()}<br/>
      ${this.getCommittedText(attempt!)}
      ${this.displaySubmittableChanges(attempt!)}
      <br/>
      <b>State of Verifiers</b>
      ${this.displayVerifiers(attempt!)}
    </span>
    `);
  }

  private displayVerifiers(attempt: ChangeAttempt): TemplateResult[] {
    if (!attempt.verifiers_statuses || !attempt.verifiers_statuses.length) {
      return [];
    }
    return attempt.verifiers_statuses.map((verifier) => html`
      <table class="verifier-table ${this.getStateClass(verifier!.state)}">
        <tr>
          <td width=33%>
            ${verifier?.name}
          </td>
          <td width=33%>
          ${verifier?.state}
          </td>
          <td width=33%>
          ${this.getVerificationDurationText(verifier!.start_ts, verifier!.stop_ts)}
          </td>
        </tr>
        <tr>
          <td colspan=3>
          ${this.displayReason(verifier!.reason)}
          </td>
        </tr>
      </table>
    `);
  }

  private displayReason(reason: string): TemplateResult[] {
    const lines = reason.split('\n');
    return lines.map((line) => html`
      ${escapeAndLinkify(line)}<br/>
    `);
  }

  private getStateClass(state: VerifierState): string {
    return VerifierStateToClassName[state];
  }

  private getVerificationDurationText(start: number, stop: number): TemplateResult {
    let endTime = Date.now();
    let additionalInfo = '(still running)';
    if (stop) {
      endTime = stop * 1000;
      additionalInfo = '';
    }
    return html`Total duration: ${diffDate(start * 1000, endTime)} ${additionalInfo}<br/>`;
  }

  private displaySubmittableChanges(attempt: ChangeAttempt): TemplateResult {
    if (!attempt.dry_run && attempt.submittable_changes && attempt.submittable_changes.length > 0) {
      return html`<b>Changes submitted together</b>
      <ul>
        ${attempt.submittable_changes.map((ch) => html`<li><a href="http://skia-review.googlesource.com/c/${ch}" target=_blank>${ch}</a></li>`)}
      </ul>
      `;
    }
    return html``;
  }

  private getDryRunText(attempt: ChangeAttempt): TemplateResult {
    if (attempt.dry_run) {
      return html`(Dry-Run)`;
    }
    return html`(CQ)`;
  }

  private getTotalDurationText(attempt: ChangeAttempt): TemplateResult {
    let endTime = Date.now();
    let additionalInfo = '(still running)';
    if (attempt.stop_ts) {
      endTime = attempt.stop_ts * 1000;
      additionalInfo = '';
    }
    if (attempt.cq_abandoned) {
      additionalInfo = '(was abandoned)';
    }
    return html`${diffDate(attempt?.start_ts as number * 1000, endTime)} ${additionalInfo}`;
  }

  private getCommittedText(attempt: ChangeAttempt): TemplateResult {
    if (attempt.committed_ts) {
      const d = new Date(attempt.committed_ts * 1000).toLocaleString();
      return html`<b>Patch committed at</b> ${d}<br/>`;
    }
    return html``;
  }

  private fetchAttempts() {
    if (!this.changeID || !this.patchsetID) {
      return;
    }
    const detail: GetChangeAttemptsRequest = {
      change_id: this.changeID,
      patchset_id: this.patchsetID,
    };
    doImpl<GetChangeAttemptsRequest, GetChangeAttemptsResponse>('/_/get_change_attempts', detail, (json: GetChangeAttemptsResponse) => {
      this.changeAttempts = json.change_attempts!;
      this.noData = !this.changeAttempts || this.changeAttempts.attempts!.length === 0;
      this.updatingData = false;
      this._render();
    });
  }
}

define('verifiers-detail-sk', VerifiersDetailSk);
