/**
 * @license
 * Copyright (C) 2020 Red Hat
 *
 * 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 {PluginApi} from '@gerritcodereview/typescript-api/plugin';
import {
  ChangeInfo,
  ChangeMessageInfo,
  RevisionInfo,
} from '@gerritcodereview/typescript-api/rest-api';
import {LitElement, html, css, nothing} from 'lit';
import {customElement, property, state} from 'lit/decorators.js';

declare global {
  interface HTMLElementTagNameMap {
    'zuul-summary-status-tab': ZuulSummaryStatusTab;
  }
}

interface ZuulConfig {
  enabled?: boolean;
}

interface ZuulJobResult {
  job: string;
  link?: string;
  result: string;
  errormsg?: string;
  time?: string;
}

interface ZuulTableItem {
  succeeded: boolean;
  author_id?: number;
  author_name: string;
  revision?: string | number;
  pipeline: string;
  rechecks: number;
  date: Date;
  gr_date: string;
  results: ZuulJobResult[];
}

const ZUUL_PRIORITY = [22348];

function priority(authorId?: number) {
  const index = authorId === undefined ? -1 : ZUUL_PRIORITY.indexOf(authorId);
  return index === -1 ? Number.MAX_SAFE_INTEGER : index;
}

@customElement('zuul-summary-status-tab')
export class ZuulSummaryStatusTab extends LitElement {
  @property({type: Object})
  plugin!: PluginApi;

  @property({type: Object}) change?: ChangeInfo;

  @property({type: Object}) revision?: RevisionInfo;

  @state() private _enabled? = false;

  @state() private __table: ZuulTableItem[] = [];

  static override get styles() {
    return [
      css`
        table {
          table-layout: fixed;
          width: 100%;
          border-collapse: collapse;
        }
        th,
        td {
          text-align: left;
          padding: 2px;
        }
        th {
          background-color: var(--background-color-primary, #f7ffff);
          font-weight: normal;
          color: var(--primary-text-color, rgb(33, 33, 33));
        }
        thead tr th:first-of-type,
        tbody tr td:first-of-type {
          padding-left: 12px;
        }
        a:link,
        a:visited {
          color: var(--link-color);
        }
        tr:nth-child(even) {
          background-color: var(--background-color-secondary, #f2f2f2);
        }
        tr:nth-child(odd) {
          background-color: var(--background-color-tertiary, #f7ffff);
        }
        tr:hover td {
          background-color: var(--hover-background-color, #fffed);
        }
        .status-SUCCESS {
          color: green;
        }
        .status-FAILURE,
        .status-ERROR,
        .status-RETRY_LIMIT {
          color: red;
        }
        .status-SKIPPED {
          color: #73bcf7;
        }
        .status-ABORTED,
        .status-MERGER_FAILURE,
        .status-NODE_FAILURE,
        .status-TIMED_OUT,
        .status-POST_FAILURE,
        .status-CONFIG_ERROR,
        .status-DISK_FULL {
          color: orange;
        }
        .date {
          color: var(--deemphasized-text-color);
        }
      `,
    ];
  }

  override updated(changed: Map<string, unknown>) {
    if (changed.has('change')) void this._processChange(this.change);
  }

  override render() {
    if (!this._enabled) {
      return html`Zuul integration is not enabled.`;
    }

    return html`
      ${this.__table.map(
        item => html`
          <div style="padding-bottom:2px;">
            <table>
              <thead>
                <tr>
                  <th>
                    ${item.succeeded
                      ? html`<gr-icon
                          icon="check"
                          style="color:var(--success-foreground)"
                        ></gr-icon>`
                      : html`<gr-icon
                          icon="close"
                          style="color:var(--error-foreground)"
                        ></gr-icon>`}
                    <b>${item.author_name}</b> on Patchset
                    <b>${item.revision}</b> in pipeline <b>${item.pipeline}</b>
                  </th>
                  <th>
                    ${item.rechecks ? html`${item.rechecks} rechecks` : nothing}
                  </th>
                  <th class="date">
                    <gr-date-formatter
                      show-date-and-time
                      date-str="${item.gr_date}"
                    ></gr-date-formatter>
                  </th>
                </tr>
              </thead>
              <tbody>
                ${item.results.map(
                  job => html`
                    <tr>
                      <td>
                        ${job.link
                          ? html`<a href="${job.link}">${job.job}</a>`
                          : html`<span
                              style="color: var(--secondary-text-color)"
                              >${job.job}</span
                            >`}
                      </td>
                      <td>
                        <span
                          class=${`status-${job.result}`}
                          title=${job.errormsg ?? ''}
                          >${job.result}</span
                        >
                      </td>
                      <td>${job.time}</td>
                    </tr>
                  `,
                )}
              </tbody>
            </table>
          </div>
        `,
      )}
    `;
  }

  private async _processChange(change?: ChangeInfo) {
    if (!change) return;
    this._enabled = await this._projectEnabled(change.project);
    if (this._enabled) this._processMessages(change);
  }

  private async _projectEnabled(project: string): Promise<boolean | undefined> {
    try {
      const config = (await this.plugin
        .restApi()
        .get(
          `/projects/${encodeURIComponent(project)}/${encodeURIComponent(
            this.plugin.getPluginName(),
          )}~config`,
        )) as ZuulConfig;
      return config?.enabled;
    } catch (error) {
      console.warn(error);
      return false;
    }
  }

  private _match_message_via_tag(msg: ChangeMessageInfo) {
    return !!msg.tag?.startsWith('autogenerated:zuul');
  }

  private _match_message_via_regex(msg: ChangeMessageInfo) {
    return /^(.* CI|Zuul)/.test(msg.author?.name ?? '');
  }

  private _get_status_and_pipeline(
    msg: ChangeMessageInfo,
  ): [string, string] | undefined {
    const fullMatch = /^Build (\w+) \(([\w]+) pipeline\)\./gm.exec(msg.message);
    if (fullMatch) return [fullMatch[1], fullMatch[2]];
    const simpleMatch = /^Build (\w+)\./gm.exec(msg.message);
    if (simpleMatch) return [simpleMatch[1], 'unknown'];
    return undefined;
  }

  private _processMessages(change: ChangeInfo) {
    const table: ZuulTableItem[] = [];

    (change.messages ?? []).forEach((message: ChangeMessageInfo) => {
      if (
        !(
          this._match_message_via_tag(message) ||
          this._match_message_via_regex(message)
        )
      )
        return;

      const date = new Date(message.date);
      const revision = message._revision_number;
      const statusAndPipeline = this._get_status_and_pipeline(message);
      if (!statusAndPipeline) return;
      const [status, pipeline] = statusAndPipeline;
      const authorId = message.author?._account_id;

      const existingIdx = table.findIndex(
        entry => entry.author_id === authorId && entry.pipeline === pipeline,
      );

      let rechecks = 0;
      if (existingIdx !== -1 && table[existingIdx].revision === revision) {
        rechecks = table[existingIdx].rechecks + 1;
      }

      const results: ZuulJobResult[] = [];
      const resultRe =
        /^- (?<job>[^ ]+) (?:(?<link>https?:\/\/[^ ]+)|[^ ]+) : ((ERROR (?<errormsg>.*?) in (?<errtime>.*))|(?<result>[^ ]+)( in (?<time>.*))?)/;

      message.message.split('\n').forEach((line: string) => {
        const match = resultRe.exec(line);
        const groups = match?.groups;
        if (!groups) return;
        const result = groups.errormsg ? 'ERROR' : groups.result;
        if (!groups.job || !result) return;
        results.push({
          job: groups.job,
          link: result === 'SKIPPED' ? '' : groups.link,
          result,
          errormsg: groups.errormsg,
          time: groups.errormsg ? groups.errtime : groups.time,
        });
      });

      const row: ZuulTableItem = {
        author_name: message.author?.name ?? '',
        author_id: authorId,
        revision,
        rechecks,
        date,
        gr_date: message.date,
        succeeded: status === 'succeeded',
        pipeline,
        results,
      };

      if (existingIdx === -1) {
        table.push(row);
      } else {
        table[existingIdx] = row;
      }
    });

    this.__table = table.sort((a, b) => {
      const pa = priority(a.author_id);
      const pb = priority(b.author_id);
      return pa - pb || b.date.getTime() - a.date.getTime();
    });
  }
}
