/**
 * @license
 * Copyright (C) 2021 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, nothing} from 'lit-html';
import './gr-related-change';
import {classMap} from 'lit-html/directives/class-map';
import {GrLitElement} from '../../lit/gr-lit-element';
import {customElement, property, css} from 'lit-element';
import {sharedStyles} from '../../../styles/shared-styles';
import {
  SubmittedTogetherInfo,
  ChangeInfo,
  RelatedChangeAndCommitInfo,
  RelatedChangesInfo,
  PatchSetNum,
  CommitId,
} from '../../../types/common';
import {appContext} from '../../../services/app-context';
import {ParsedChangeInfo} from '../../../types/types';
import {GerritNav} from '../../core/gr-navigation/gr-navigation';
import {pluralize} from '../../../utils/string-util';
import {getRevisionKey, isChangeInfo} from '../../../utils/change-util';

/** What is the maximum number of shown changes in collapsed list? */
const MAX_CHANGES_WHEN_COLLAPSED = 3;

@customElement('gr-related-changes-list-experimental')
export class GrRelatedChangesListExperimental extends GrLitElement {
  @property()
  change?: ParsedChangeInfo;

  @property({type: String})
  patchNum?: PatchSetNum;

  @property()
  _submittedTogether?: SubmittedTogetherInfo = {
    changes: [],
    non_visible_changes: 0,
  };

  @property()
  _relatedResponse?: RelatedChangesInfo = {changes: []};

  private readonly restApiService = appContext.restApiService;

  static get styles() {
    return [
      sharedStyles,
      css`
        .title {
          font-weight: var(--font-weight-bold);
          color: var(--deemphasized-text-color);
          padding-left: var(--metadata-horizontal-padding);
        }
        h4 {
          display: flex;
        }
        /* This is a hacky solution from old gr-related-change-list
         * TODO(milutin): find layout without needing it
         */
        h4:before,
        gr-related-change:before {
          content: ' ';
          flex-shrink: 0;
          width: 1.2em;
        }
        .note {
          color: var(--error-text-color);
        }
      `,
    ];
  }

  render() {
    const relatedChanges = this._relatedResponse?.changes ?? [];
    let showWhenCollapsedPredicate = this.showWhenCollapsedPredicateFactory(
      relatedChanges.length,
      relatedChanges.findIndex(relatedChange =>
        this._changesEqual(relatedChange, this.change)
      )
    );
    const connectedRevisions = this._computeConnectedRevisions(
      this.change,
      this.patchNum,
      relatedChanges
    );
    const relatedChangeSection = html` <section
      class="relatedChanges"
      ?hidden=${!relatedChanges.length}
    >
      <h4 class="title">Relation chain</h4>
      <gr-related-collapse .length=${relatedChanges.length}>
        ${relatedChanges.map(
          (change, index) =>
            html`<gr-related-change
              class="${classMap({
                ['show-when-collapsed']: showWhenCollapsedPredicate(index),
              })}"
              .isCurrentChange="${this._changesEqual(change, this.change)}"
              .change="${change}"
              .connectedRevisions="${connectedRevisions}"
              .href="${change?._change_number
                ? GerritNav.getUrlForChangeById(
                    change._change_number,
                    change.project,
                    change._revision_number as PatchSetNum
                  )
                : ''}"
              .showChangeStatus=${true}
              >${change.commit.subject}</gr-related-change
            >`
        )}
      </gr-related-collapse>
    </section>`;

    const submittedTogetherChanges = this._submittedTogether?.changes ?? [];
    const countNonVisibleChanges =
      this._submittedTogether?.non_visible_changes ?? 0;
    showWhenCollapsedPredicate = this.showWhenCollapsedPredicateFactory(
      submittedTogetherChanges.length,
      submittedTogetherChanges.findIndex(relatedChange =>
        this._changesEqual(relatedChange, this.change)
      )
    );
    const submittedTogetherSection = html`<section
      id="submittedTogether"
      ?hidden=${!submittedTogetherChanges?.length &&
      !this._submittedTogether?.non_visible_changes}
    >
      <h4 class="title">Submitted together</h4>
      <gr-related-collapse .length=${submittedTogetherChanges.length}>
        ${submittedTogetherChanges.map(
          (change, index) =>
            html`<gr-related-change
              class="${classMap({
                ['show-when-collapsed']: showWhenCollapsedPredicate(index),
              })}"
              .currentChange="${this._changesEqual(change, this.change)}"
              .change="${change}"
              .href="${GerritNav.getUrlForChangeById(
                change._number,
                change.project
              )}"
              .showSubmittableCheck=${true}
              >${change.project}: ${change.branch}:
              ${change.subject}</gr-related-change
            >`
        )}
      </gr-related-collapse>
      <div class="note" ?hidden=${!countNonVisibleChanges}>
        (+ ${pluralize(countNonVisibleChanges, 'non-visible change')})
      </div>
    </section>`;

    return html`${relatedChangeSection}${submittedTogetherSection}`;
  }

  showWhenCollapsedPredicateFactory(length: number, highlightIndex: number) {
    return (index: number) => {
      if (highlightIndex === 0) return index <= MAX_CHANGES_WHEN_COLLAPSED - 1;
      if (highlightIndex === length - 1)
        return index >= length - MAX_CHANGES_WHEN_COLLAPSED;
      return (
        highlightIndex - MAX_CHANGES_WHEN_COLLAPSED + 2 <= index &&
        index <= highlightIndex + MAX_CHANGES_WHEN_COLLAPSED - 2
      );
    };
  }

  reload() {
    if (!this.change) return Promise.reject(new Error('change missing'));
    if (!this.patchNum) return Promise.reject(new Error('patchNum missing'));
    const promises: Array<Promise<void>> = [
      this.restApiService
        .getRelatedChanges(this.change._number, this.patchNum)
        .then(response => {
          if (!response) {
            throw new Error('getRelatedChanges returned undefined response');
          }
          this._relatedResponse = response;
        }),
      this.restApiService
        .getChangesSubmittedTogether(this.change._number)
        .then(response => {
          this._submittedTogether = response;
        }),
    ];

    return Promise.all(promises);
  }

  /**
   * Do the given objects describe the same change? Compares the changes by
   * their numbers.
   */
  _changesEqual(
    a?: ChangeInfo | RelatedChangeAndCommitInfo,
    b?: ChangeInfo | ParsedChangeInfo | RelatedChangeAndCommitInfo
  ) {
    const aNum = this._getChangeNumber(a);
    const bNum = this._getChangeNumber(b);
    return aNum === bNum;
  }

  /**
   * Get the change number from either a ChangeInfo (such as those included in
   * SubmittedTogetherInfo responses) or get the change number from a
   * RelatedChangeAndCommitInfo (such as those included in a
   * RelatedChangesInfo response).
   */
  _getChangeNumber(
    change?: ChangeInfo | ParsedChangeInfo | RelatedChangeAndCommitInfo
  ) {
    // Default to 0 if change property is not defined.
    if (!change) return 0;

    if (isChangeInfo(change)) {
      return change._number;
    }
    return change._change_number;
  }

  /*
   * A list of commit ids connected to change to understand if other change
   * is direct or indirect ancestor / descendant.
   */
  _computeConnectedRevisions(
    change?: ParsedChangeInfo,
    patchNum?: PatchSetNum,
    relatedChanges?: RelatedChangeAndCommitInfo[]
  ) {
    if (!patchNum || !relatedChanges || !change) {
      return [];
    }

    const connected: CommitId[] = [];
    const changeRevision = getRevisionKey(change, patchNum);
    const commits = relatedChanges.map(c => c.commit);
    let pos = commits.length - 1;

    while (pos >= 0) {
      const commit: CommitId = commits[pos].commit;
      connected.push(commit);
      // TODO(TS): Ensure that both (commit and changeRevision) are string and use === instead
      // eslint-disable-next-line eqeqeq
      if (commit == changeRevision) {
        break;
      }
      pos--;
    }
    while (pos >= 0) {
      for (let i = 0; i < commits[pos].parents.length; i++) {
        if (connected.includes(commits[pos].parents[i].commit)) {
          connected.push(commits[pos].commit);
          break;
        }
      }
      --pos;
    }
    return connected;
  }
}

@customElement('gr-related-collapse')
export class GrRelatedCollapse extends GrLitElement {
  @property()
  showAll = false;

  @property()
  length = 0;

  static get styles() {
    return [
      sharedStyles,
      css`
        gr-button {
          display: flex;
        }
        gr-button:before {
          content: ' ';
          flex-shrink: 0;
          width: 1.2em;
        }
        .collapsed ::slotted(gr-related-change.show-when-collapsed) {
          display: flex;
        }
        .collapsed ::slotted(gr-related-change) {
          display: none;
        }
        ::slotted(gr-related-change) {
          display: flex;
        }
      `,
    ];
  }

  render() {
    const collapsible = this.length > MAX_CHANGES_WHEN_COLLAPSED;
    const items = html` <div
      class="${!this.showAll && collapsible ? 'collapsed' : ''}"
    >
      <slot></slot>
    </div>`;
    let button = nothing;
    if (collapsible) {
      if (this.showAll) {
        button = html`<gr-button link="" @click="${this.toggle}"
          >Show less</gr-button
        >`;
      } else {
        button = html`<gr-button link="" @click="${this.toggle}"
          >+ ${this.length - MAX_CHANGES_WHEN_COLLAPSED} more</gr-button
        >`;
      }
    }

    return html`${items}${button}`;
  }

  private toggle(e: MouseEvent) {
    e.stopPropagation();
    this.showAll = !this.showAll;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-related-changes-list-experimental': GrRelatedChangesListExperimental;
    'gr-related-collapse': GrRelatedCollapse;
  }
}
