/**
 * @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 {html} from 'lit-html';
import {
  css,
  customElement,
  internalProperty,
  property,
  PropertyValues,
} from 'lit-element';
import {GrLitElement} from '../lit/gr-lit-element';
import {Action, CheckResult, CheckRun} from '../../api/checks';
import {
  allActions$,
  allResults$,
  allRuns$,
  checksPatchsetNumber$,
  someProvidersAreLoading$,
} from '../../services/checks/checks-model';
import './gr-checks-runs';
import './gr-checks-results';
import {sharedStyles} from '../../styles/shared-styles';
import {changeNum$, latestPatchNum$} from '../../services/change/change-model';
import {NumericChangeId, PatchSetNumber} from '../../types/common';
import {
  ActionTriggeredEvent,
  fireActionTriggered,
} from '../../services/checks/checks-util';
import {
  assertIsDefined,
  check,
  checkRequiredProperty,
} from '../../utils/common-util';
import {RunSelectedEvent} from './gr-checks-runs';
import {ChecksTabState} from '../../types/events';
import {fireAlert} from '../../utils/event-util';
import {appContext} from '../../services/app-context';
import {from, timer} from 'rxjs';
import {takeUntil} from 'rxjs/operators';

/**
 * The "Checks" tab on the Gerrit change page. Gets its data from plugins that
 * have registered with the Checks Plugin API.
 */
@customElement('gr-checks-tab')
export class GrChecksTab extends GrLitElement {
  @property()
  runs: CheckRun[] = [];

  results: CheckResult[] = [];

  actions: Action[] = [];

  @property()
  tabState?: ChecksTabState;

  @property()
  checksPatchsetNumber: PatchSetNumber | undefined = undefined;

  @property()
  latestPatchsetNumber: PatchSetNumber | undefined = undefined;

  @property()
  changeNum: NumericChangeId | undefined = undefined;

  @property()
  someProvidersAreLoading = false;

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

  private readonly checksService = appContext.checksService;

  constructor() {
    super();
    this.subscribe('runs', allRuns$);
    this.subscribe('actions', allActions$);
    this.subscribe('results', allResults$);
    this.subscribe('checksPatchsetNumber', checksPatchsetNumber$);
    this.subscribe('latestPatchsetNumber', latestPatchNum$);
    this.subscribe('changeNum', changeNum$);
    this.subscribe('someProvidersAreLoading', someProvidersAreLoading$);

    this.addEventListener('action-triggered', (e: ActionTriggeredEvent) =>
      this.handleActionTriggered(e.detail.action, e.detail.run)
    );
  }

  static get styles() {
    return [
      sharedStyles,
      css`
        :host {
          display: block;
        }
        .header {
          display: flex;
          justify-content: space-between;
          padding: var(--spacing-m) var(--spacing-l);
          border-bottom: 1px solid var(--border-color);
        }
        .action {
          margin-left: var(--spacing-m);
        }
        .container {
          display: flex;
        }
        .runs {
          min-width: 300px;
          min-height: 400px;
          border-right: 1px solid var(--border-color);
        }
        .results {
          background-color: var(--background-color-secondary);
          flex-grow: 1;
        }
      `,
    ];
  }

  render() {
    const filteredRuns = this.runs.filter(
      r =>
        this.selectedRuns.length === 0 ||
        this.selectedRuns.includes(r.checkName)
    );
    return html`
      <div class="header">
        <div class="left">
          <gr-dropdown-list
            value="${this.checksPatchsetNumber}"
            .items="${this.createPatchsetDropdownItems()}"
            @value-change="${this.onPatchsetSelected}"
          ></gr-dropdown-list>
          <span ?hidden="${!this.someProvidersAreLoading}">Loading...</span>
        </div>
        <div class="right">
          ${this.actions.map(this.renderAction)}
        </div>
      </div>
      <div class="container">
        <gr-checks-runs
          class="runs"
          .runs="${this.runs}"
          .selectedRuns="${this.selectedRuns}"
          @run-selected="${this.handleRunSelected}"
        ></gr-checks-runs>
        <gr-checks-results
          class="results"
          .runs="${filteredRuns}"
        ></gr-checks-results>
      </div>
    `;
  }

  private onPatchsetSelected(e: CustomEvent<{value: string}>) {
    const patchset = Number(e.detail.value);
    check(!isNaN(patchset), 'selected patchset must be a number');
    this.checksService.setPatchset(patchset as PatchSetNumber);
  }

  private createPatchsetDropdownItems() {
    return Array.from(Array(this.latestPatchsetNumber), (_, i) => {
      assertIsDefined(this.latestPatchsetNumber, 'latestPatchsetNumber');
      const index = this.latestPatchsetNumber - i;
      const postfix = index === this.latestPatchsetNumber ? ' (latest)' : '';
      return {
        value: `${index}`,
        text: `Patchset ${index}${postfix}`,
      };
    });
  }

  protected updated(changedProperties: PropertyValues) {
    super.updated(changedProperties);
    if (changedProperties.has('tabState')) {
      const check = this.tabState?.checkName;
      if (check) {
        this.selectedRuns = [check];
      }
    }
  }

  renderAction(action: Action) {
    return html`<gr-checks-top-level-action
      .action="${action}"
    ></gr-checks-top-level-action>`;
  }

  handleActionTriggered(action: Action, run?: CheckRun) {
    if (!this.changeNum) return;
    if (!this.checksPatchsetNumber) return;
    const promise = action.callback(
      this.changeNum,
      this.checksPatchsetNumber,
      run?.attempt,
      run?.externalId,
      run?.checkName,
      action.name
    );
    // Plugins *should* return a promise, but you never know ...
    if (promise?.then) {
      const prefix = `Triggering action '${action.name}'`;
      fireAlert(this, `${prefix} ...`);
      from(promise)
        // If the action takes longer than 5 seconds, then most likely the
        // user is either not interested or the result not relevant anymore.
        .pipe(takeUntil(timer(5000)))
        .subscribe(result => {
          if (result.errorMessage) {
            fireAlert(this, `${prefix} failed with ${result.errorMessage}.`);
          } else {
            fireAlert(this, `${prefix} successful.`);
            this.checksService.reloadForCheck(run?.checkName);
          }
        });
    } else {
      fireAlert(this, `Action '${action.name}' triggered.`);
    }
  }

  handleRunSelected(e: RunSelectedEvent) {
    this.toggleSelected(e.detail.checkName);
  }

  toggleSelected(checkName: string) {
    if (this.selectedRuns.includes(checkName)) {
      this.selectedRuns = this.selectedRuns.filter(r => r !== checkName);
    } else {
      this.selectedRuns = [...this.selectedRuns, checkName];
    }
  }
}

@customElement('gr-checks-top-level-action')
export class GrChecksTopLevelAction extends GrLitElement {
  @property()
  action!: Action;

  connectedCallback() {
    super.connectedCallback();
    checkRequiredProperty(this.action, 'action');
  }

  render() {
    return html`
      <gr-button link class="action" @click="${this.handleClick}"
        >${this.action.name}</gr-button
      >
    `;
  }

  handleClick() {
    fireActionTriggered(this, this.action);
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-checks-tab': GrChecksTab;
    'gr-checks-top-level-action': GrChecksTopLevelAction;
  }
}
