/**
 * @license
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import {classMap} from 'lit/directives/class-map';
import './gr-hovercard-run';
import {css, html, LitElement, nothing, PropertyValues} from 'lit';
import {customElement, property, query, state} from 'lit/decorators';
import './gr-checks-attempt';
import {Action, Link, RunStatus} from '../../api/checks';
import {sharedStyles} from '../../styles/shared-styles';
import {
  AttemptDetail,
  compareByWorstCategory,
  headerForStatus,
  iconFor,
  iconForRun,
  PRIMARY_STATUS_ACTIONS,
  primaryRunAction,
  worstCategory,
} from '../../services/checks/checks-util';
import {
  allRunsSelectedPatchset$,
  CheckRun,
  ChecksPatchset,
  ErrorMessages,
  errorMessagesLatest$,
  fakeActions,
  fakeLinks,
  fakeRun0,
  fakeRun1,
  fakeRun2,
  fakeRun3,
  fakeRun4Att,
  loginCallbackLatest$,
  updateStateSetResults,
} from '../../services/checks/checks-model';
import {assertIsDefined} from '../../utils/common-util';
import {modifierPressed, whenVisible} from '../../utils/dom-util';
import {
  fireAttemptSelected,
  fireRunSelected,
  fireRunSelectionReset,
} from './gr-checks-util';
import {ChecksTabState} from '../../types/events';
import {charsOnly} from '../../utils/string-util';
import {appContext} from '../../services/app-context';
import {KnownExperimentId} from '../../services/flags/flags';
import {subscribe} from '../lit/subscription-controller';
import {fontStyles} from '../../styles/gr-font-styles';

@customElement('gr-checks-run')
export class GrChecksRun extends LitElement {
  static override get styles() {
    return [
      sharedStyles,
      css`
        :host {
          display: block;
          --thick-border: 6px;
        }
        .chip {
          display: flex;
          justify-content: space-between;
          border: 1px solid var(--border-color);
          border-radius: var(--border-radius);
          padding: var(--spacing-s) var(--spacing-m);
          margin-top: var(--spacing-s);
          cursor: pointer;
        }
        .left {
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
          flex-shrink: 1;
        }
        .middle {
          /* extra space must go between middle and right */
          flex-grow: 1;
          white-space: nowrap;
        }
        .middle gr-checks-attempt {
          margin-left: var(--spacing-s);
        }
        .name {
          font-weight: var(--font-weight-bold);
        }
        .chip.error {
          border-left: var(--thick-border) solid var(--error-foreground);
        }
        .chip.warning {
          border-left: var(--thick-border) solid var(--warning-foreground);
        }
        .chip.info-outline {
          border-left: var(--thick-border) solid var(--info-foreground);
        }
        .chip.check-circle-outline {
          border-left: var(--thick-border) solid var(--success-foreground);
        }
        .chip.timelapse {
          border-left: var(--thick-border) solid var(--border-color);
        }
        .chip.placeholder {
          border-left: var(--thick-border) solid var(--border-color);
        }
        .chip.placeholder iron-icon {
          display: none;
        }
        iron-icon.error {
          color: var(--error-foreground);
        }
        iron-icon.warning {
          color: var(--warning-foreground);
        }
        iron-icon.info-outline {
          color: var(--info-foreground);
        }
        iron-icon.check-circle-outline {
          color: var(--success-foreground);
        }
        div.chip:hover {
          background-color: var(--hover-background-color);
        }
        div.chip:focus-within {
          background-color: var(--selection-background-color);
        }
        /* Additional 'div' for increased specificity. */
        div.chip.selected {
          border: 1px solid var(--selected-background);
          background-color: var(--selected-background);
          padding-left: calc(var(--spacing-m) + var(--thick-border) - 1px);
        }
        div.chip.selected .name,
        div.chip.selected iron-icon.filter {
          color: var(--selected-foreground);
        }
        gr-checks-action {
          /* The button should fit into the 20px line-height. The negative
             margin provides the extra space needed for the vertical padding.
             Alternatively we could have set the vertical padding to 0, but
             that would not have been a nice click target. */
          margin: calc(0px - var(--spacing-s));
          margin-left: var(--spacing-s);
        }
        .attemptDetails {
          padding-bottom: var(--spacing-s);
        }
        .attemptDetail {
          /* This is thick-border (6) + spacing-m (8) + icon (20) + padding. */
          padding-left: 39px;
          padding-top: var(--spacing-s);
        }
        .attemptDetail input {
          width: 14px;
          height: 14px;
          /* The next 3 are for placing in the middle of 20px line-height. */
          vertical-align: top;
          position: relative;
          top: 3px;
          margin-right: var(--spacing-s);
        }
        .statusLinkIcon {
          color: var(--link-color);
          margin-left: var(--spacing-s);
        }
      `,
    ];
  }

  @query('.chip')
  chipElement?: HTMLElement;

  @property()
  run!: CheckRun;

  @property()
  selected = false;

  @property()
  selectedAttempt?: number;

  @property()
  deselected = false;

  @property()
  shouldRender = false;

  override firstUpdated() {
    assertIsDefined(this.chipElement, 'chip element');
    whenVisible(
      this.chipElement,
      () => this.setAttribute('shouldRender', 'true'),
      200
    );
  }

  protected override updated(changedProperties: PropertyValues) {
    super.updated(changedProperties);

    // For some reason the browser does not pick up the correct `checked` state
    // that is set in renderAttempt(). So we have to set it programmatically
    // here.
    const selectedAttempt = this.selectedAttempt ?? this.run.attempt;
    const inputToBeSelected = this.shadowRoot?.querySelector(
      `.attemptDetails input#attempt-${selectedAttempt}`
    ) as HTMLInputElement | undefined;
    if (inputToBeSelected) {
      inputToBeSelected.checked = true;
    }
  }

  override render() {
    if (!this.shouldRender) return html`<div class="chip">Loading ...</div>`;

    const icon = iconForRun(this.run);
    const classes = {
      chip: true,
      [icon]: true,
      selected: this.selected,
      deselected: this.deselected,
    };
    const action = primaryRunAction(this.run);

    return html`
      <div
        @click="${this.handleChipClick}"
        @keydown="${this.handleChipKey}"
        class="${classMap(classes)}"
        tabindex="0"
      >
        <div class="left">
          <gr-hovercard-run .run="${this.run}"></gr-hovercard-run>
          ${this.renderFilterIcon()}
          <iron-icon class="${icon}" icon="gr-icons:${icon}"></iron-icon>
          ${this.renderAdditionalIcon()}
          <span class="name">${this.run.checkName}</span>
        </div>
        <div class="middle">
          <gr-checks-attempt .run="${this.run}"></gr-checks-attempt>
          ${this.renderStatusLink()}
        </div>
        <div class="right">
          ${action
            ? html`<gr-checks-action .action="${action}"></gr-checks-action>`
            : ''}
        </div>
      </div>
      <div
        class="attemptDetails"
        ?hidden="${this.run.isSingleAttempt || !this.selected}"
      >
        ${this.run.attemptDetails.map(a => this.renderAttempt(a))}
      </div>
    `;
  }

  isSelected(detail: AttemptDetail) {
    // this.selectedAttempt may be undefined, then choose the latest attempt,
    // which is what this.run has.
    const selectedAttempt = this.selectedAttempt ?? this.run.attempt;
    return detail.attempt === selectedAttempt;
  }

  renderAttempt(detail: AttemptDetail) {
    const checkNameId = charsOnly(this.run.checkName).toLowerCase();
    const id = `attempt-${detail.attempt}`;
    const icon = detail.icon;
    const wasNotRun = icon === iconFor(RunStatus.RUNNABLE);
    return html`<div class="attemptDetail">
      <input
        type="radio"
        id="${id}"
        name="${`${checkNameId}-attempt-choice`}"
        ?checked="${this.isSelected(detail)}"
        ?disabled="${!this.isSelected(detail) && wasNotRun}"
        @change="${() => this.handleAttemptChange(detail)}"
      />
      <iron-icon class="${icon}" icon="gr-icons:${icon}"></iron-icon>
      <label for="${id}">
        Attempt ${detail.attempt}${wasNotRun ? ' (not run)' : ''}
      </label>
    </div>`;
  }

  handleAttemptChange(detail: AttemptDetail) {
    if (!this.isSelected(detail)) {
      fireAttemptSelected(this, this.run.checkName, detail.attempt);
    }
  }

  renderStatusLink() {
    const link = this.run.statusLink;
    if (!link) return;
    return html`
      <a href="${link}" target="_blank" @click="${this.onLinkClick}"
        ><iron-icon
          class="statusLinkIcon"
          icon="gr-icons:launch"
          aria-label="external link to run status details"
        ></iron-icon>
        <paper-tooltip offset="5">Link to run status details</paper-tooltip>
      </a>
    `;
  }

  private onLinkClick(e: MouseEvent) {
    // Prevents handleChipClick() from reacting to <a> link clicks.
    e.stopPropagation();
  }

  renderFilterIcon() {
    if (!this.selected) return;
    return html`
      <iron-icon class="filter" icon="gr-icons:filter"></iron-icon>
    `;
  }

  /**
   * For RUNNING we also want to render an icon representing the worst result
   * that has been reported until now - if there are any results already.
   */
  renderAdditionalIcon() {
    if (this.run.status !== RunStatus.RUNNING) return nothing;
    const category = worstCategory(this.run);
    if (!category) return nothing;
    const icon = iconFor(category);
    return html`
      <iron-icon class="${icon}" icon="gr-icons:${icon}"></iron-icon>
    `;
  }

  private handleChipClick(e: MouseEvent) {
    e.stopPropagation();
    e.preventDefault();
    fireRunSelected(this, this.run.checkName);
  }

  private handleChipKey(e: KeyboardEvent) {
    if (modifierPressed(e)) return;
    // Only react to `return` and `space`.
    if (e.keyCode !== 13 && e.keyCode !== 32) return;
    e.preventDefault();
    e.stopPropagation();
    fireRunSelected(this, this.run.checkName);
  }
}

@customElement('gr-checks-runs')
export class GrChecksRuns extends LitElement {
  @query('#filterInput')
  filterInput?: HTMLInputElement;

  @state()
  filterRegExp = new RegExp('');

  @property()
  runs: CheckRun[] = [];

  @property({type: Boolean, reflect: true})
  collapsed = false;

  @property()
  selectedRuns: string[] = [];

  /** Maps checkName to selected attempt number. `undefined` means `latest`. */
  @property()
  selectedAttempts: Map<string, number | undefined> = new Map<
    string,
    number | undefined
  >();

  @property()
  tabState?: ChecksTabState;

  @property()
  errorMessages: ErrorMessages = {};

  @property()
  loginCallback?: () => void;

  private isSectionExpanded = new Map<RunStatus, boolean>();

  private flagService = appContext.flagsService;

  private checksService = appContext.checksService;

  constructor() {
    super();
    subscribe(this, allRunsSelectedPatchset$, x => (this.runs = x));
    subscribe(this, errorMessagesLatest$, x => (this.errorMessages = x));
    subscribe(this, loginCallbackLatest$, x => (this.loginCallback = x));
  }

  static override get styles() {
    return [
      sharedStyles,
      fontStyles,
      css`
        :host {
          display: block;
        }
        :host(:not([collapsed])) {
          min-width: 320px;
          padding: var(--spacing-l) var(--spacing-xl) var(--spacing-xl)
            var(--spacing-xl);
        }
        :host([collapsed]) {
          padding: var(--spacing-l) 0;
        }
        .title {
          display: flex;
        }
        .title .flex-space {
          flex-grow: 1;
        }
        .title gr-button {
          --padding: var(--spacing-s) var(--spacing-m);
          white-space: nowrap;
        }
        .title gr-button.expandButton {
          --padding: var(--spacing-xs) var(--spacing-s);
        }
        :host(:not([collapsed])) .expandButton {
          margin-right: calc(0px - var(--spacing-m));
        }
        .expandIcon {
          width: var(--line-height-h3);
          height: var(--line-height-h3);
        }
        .sectionHeader {
          padding-top: var(--spacing-l);
          text-transform: capitalize;
          cursor: default;
        }
        .sectionHeader h3 {
          display: inline-block;
        }
        .collapsed .sectionRuns {
          display: none;
        }
        .collapsed {
          border-bottom: 1px solid var(--border-color);
          padding-bottom: var(--spacing-m);
        }
        input#filterInput {
          margin-top: var(--spacing-m);
          padding: var(--spacing-s) var(--spacing-m);
          width: 100%;
        }
        .testing {
          margin-top: var(--spacing-xxl);
          color: var(--deemphasized-text-color);
        }
        .testing gr-button {
          min-width: 25px;
        }
        .testing * {
          visibility: hidden;
        }
        .testing:hover * {
          visibility: visible;
        }
        .login,
        .error {
          padding: var(--spacing-m);
          color: var(--primary-text-color);
          margin-top: var(--spacing-m);
          max-width: 400px;
        }
        .error {
          display: flex;
          background-color: var(--error-background);
        }
        .error iron-icon {
          color: var(--error-foreground);
          margin-right: var(--spacing-m);
        }
        .login {
          background: var(--info-background);
        }
        .login iron-icon {
          color: var(--info-foreground);
        }
        .login .buttonRow {
          text-align: right;
          margin-top: var(--spacing-xl);
        }
        .login gr-button {
          margin: 0 var(--spacing-s);
        }
      `,
    ];
  }

  protected override updated(changedProperties: PropertyValues) {
    super.updated(changedProperties);
    if (changedProperties.has('tabState') && this.tabState) {
      const {statusOrCategory} = this.tabState;
      if (
        statusOrCategory === RunStatus.RUNNING ||
        statusOrCategory === RunStatus.RUNNABLE
      ) {
        this.updateComplete.then(() => {
          const s = statusOrCategory.toString().toLowerCase();
          const el = this.shadowRoot?.querySelector(`.${s} .sectionHeader`);
          el?.scrollIntoView({block: 'center'});
        });
      }
    }
  }

  override render() {
    if (this.collapsed) {
      return html`${this.renderCollapseButton()}`;
    }
    return html`
      <h2 class="title">
        <div class="heading-2">Runs</div>
        <div class="flex-space"></div>
        ${this.renderTitleButtons()} ${this.renderCollapseButton()}
      </h2>
      ${this.renderErrors()} ${this.renderSignIn()}
      <input
        id="filterInput"
        type="text"
        placeholder="Filter runs by regular expression"
        ?hidden="${!this.showFilter()}"
        @input="${this.onInput}"
      />
      ${this.renderSection(RunStatus.RUNNING)}
      ${this.renderSection(RunStatus.COMPLETED)}
      ${this.renderSection(RunStatus.RUNNABLE)} ${this.renderFakeControls()}
    `;
  }

  private renderErrors() {
    return Object.entries(this.errorMessages).map(
      ([plugin, message]) =>
        html`
          <div class="error">
            <div class="left">
              <iron-icon icon="gr-icons:error"></iron-icon>
            </div>
            <div class="right">
              <div class="message">
                Error while fetching results for ${plugin}:<br />${message}
              </div>
            </div>
          </div>
        `
    );
  }

  private renderSignIn() {
    if (!this.loginCallback) return;
    return html`
      <div class="login">
        <div>
          <iron-icon
            class="info-outline"
            icon="gr-icons:info-outline"
          ></iron-icon>
          Sign in to Checks Plugin to see runs and results
        </div>
        <div class="buttonRow">
          <gr-button @click="${this.loginCallback}" link>Sign in</gr-button>
        </div>
      </div>
    `;
  }

  private renderTitleButtons() {
    if (this.selectedRuns.length < 2) return;
    const actions = this.selectedRuns.map(selected => {
      const run = this.runs.find(
        run => run.isLatestAttempt && run.checkName === selected
      );
      return primaryRunAction(run);
    });
    const runButtonDisabled = !actions.every(
      action =>
        action?.name === PRIMARY_STATUS_ACTIONS.RUN ||
        action?.name === PRIMARY_STATUS_ACTIONS.RERUN
    );
    return html`
      <gr-button
        class="font-normal"
        link
        @click="${() => fireRunSelectionReset(this)}"
        >Unselect All</gr-button
      >
      <gr-tooltip-content
        title="${runButtonDisabled
          ? 'Disabled. Unselect checks without a "Run" action to enable the button.'
          : ''}"
        ?has-tooltip=${runButtonDisabled}
      >
        <gr-button
          class="font-normal"
          link
          ?disabled=${runButtonDisabled}
          @click="${() => {
            actions.forEach(action => this.checksService.triggerAction(action));
          }}"
          >Run Selected</gr-button
        >
      </gr-tooltip-content>
    `;
  }

  private renderCollapseButton() {
    return html`
      <gr-tooltip-content
        has-tooltip
        title="${this.collapsed ? 'Expand runs panel' : 'Collapse runs panel'}"
      >
        <gr-button
          link
          class="expandButton"
          role="switch"
          ?aria-checked="${this.collapsed}"
          aria-label="${this.collapsed
            ? 'Expand runs panel'
            : 'Collapse runs panel'}"
          @click="${() => (this.collapsed = !this.collapsed)}"
          ><iron-icon
            class="expandIcon"
            icon="${this.collapsed
              ? 'gr-icons:chevron-right'
              : 'gr-icons:chevron-left'}"
          ></iron-icon>
        </gr-button>
      </gr-tooltip-content>
    `;
  }

  onInput() {
    assertIsDefined(this.filterInput, 'filter <input> element');
    this.filterRegExp = new RegExp(this.filterInput.value, 'i');
  }

  none() {
    updateStateSetResults('f0', [], [], [], ChecksPatchset.LATEST);
    updateStateSetResults('f1', [], [], [], ChecksPatchset.LATEST);
    updateStateSetResults('f2', [], [], [], ChecksPatchset.LATEST);
    updateStateSetResults('f3', [], [], [], ChecksPatchset.LATEST);
    updateStateSetResults('f4', [], [], [], ChecksPatchset.LATEST);
  }

  all() {
    updateStateSetResults(
      'f0',
      [fakeRun0],
      fakeActions,
      fakeLinks,
      ChecksPatchset.LATEST
    );
    updateStateSetResults('f1', [fakeRun1], [], [], ChecksPatchset.LATEST);
    updateStateSetResults('f2', [fakeRun2], [], [], ChecksPatchset.LATEST);
    updateStateSetResults('f3', [fakeRun3], [], [], ChecksPatchset.LATEST);
    updateStateSetResults('f4', fakeRun4Att, [], [], ChecksPatchset.LATEST);
  }

  toggle(
    plugin: string,
    runs: CheckRun[],
    actions: Action[] = [],
    links: Link[] = []
  ) {
    const newRuns = this.runs.includes(runs[0]) ? [] : runs;
    updateStateSetResults(
      plugin,
      newRuns,
      actions,
      links,
      ChecksPatchset.LATEST
    );
  }

  renderSection(status: RunStatus) {
    const runs = this.runs
      .filter(r => r.isLatestAttempt)
      .filter(r => r.status === status)
      .filter(r => this.filterRegExp.test(r.checkName))
      .sort(compareByWorstCategory);
    if (runs.length === 0) return;
    const expanded = this.isSectionExpanded.get(status) ?? true;
    const expandedClass = expanded ? 'expanded' : 'collapsed';
    const icon = expanded ? 'gr-icons:expand-less' : 'gr-icons:expand-more';
    return html`
      <div class="${status.toLowerCase()} ${expandedClass}">
        <div
          class="sectionHeader"
          @click="${() => this.toggleExpanded(status)}"
        >
          <iron-icon class="expandIcon" icon="${icon}"></iron-icon>
          <h3 class="heading-3">${headerForStatus(status)}</h3>
        </div>
        <div class="sectionRuns">${runs.map(run => this.renderRun(run))}</div>
      </div>
    `;
  }

  toggleExpanded(status: RunStatus) {
    const expanded = this.isSectionExpanded.get(status) ?? true;
    this.isSectionExpanded.set(status, !expanded);
    this.requestUpdate();
  }

  renderRun(run: CheckRun) {
    const selectedRun = this.selectedRuns.includes(run.checkName);
    const selectedAttempt = this.selectedAttempts.get(run.checkName);
    const deselected = !selectedRun && this.selectedRuns.length > 0;
    return html`<gr-checks-run
      .run="${run}"
      .selected="${selectedRun}"
      .selectedAttempt="${selectedAttempt}"
      .deselected="${deselected}"
    ></gr-checks-run>`;
  }

  showFilter(): boolean {
    const show = this.runs.length > 10;
    if (!show && this.filterRegExp.source.length > 0) {
      this.filterRegExp = new RegExp('');
    }
    return show;
  }

  renderFakeControls() {
    if (!this.flagService.isEnabled(KnownExperimentId.CHECKS_DEVELOPER)) return;
    return html`
      <div class="testing">
        <div>Toggle fake runs by clicking buttons:</div>
        <gr-button link @click="${this.none}">none</gr-button>
        <gr-button
          link
          @click="${() =>
            this.toggle('f0', [fakeRun0], fakeActions, fakeLinks)}"
          >0</gr-button
        >
        <gr-button link @click="${() => this.toggle('f1', [fakeRun1])}"
          >1</gr-button
        >
        <gr-button link @click="${() => this.toggle('f2', [fakeRun2])}"
          >2</gr-button
        >
        <gr-button link @click="${() => this.toggle('f3', [fakeRun3])}"
          >3</gr-button
        >
        <gr-button link @click="${() => this.toggle('f4', fakeRun4Att)}}"
          >4</gr-button
        >
        <gr-button link @click="${this.all}">all</gr-button>
      </div>
    `;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-checks-run': GrChecksRun;
    'gr-checks-runs': GrChecksRuns;
  }
}
