/**
 * @license
 * Copyright (C) 2015 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 '../../shared/gr-account-link/gr-account-link';
import '../../shared/gr-change-star/gr-change-star';
import '../../shared/gr-change-status/gr-change-status';
import '../../shared/gr-date-formatter/gr-date-formatter';
import '../../shared/gr-icons/gr-icons';
import '../../shared/gr-limited-text/gr-limited-text';
import '../../shared/gr-tooltip-content/gr-tooltip-content';
import '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator';
import '../../plugins/gr-endpoint-param/gr-endpoint-param';
import '../gr-change-list-column-requirements-summary/gr-change-list-column-requirements-summary';
import '../gr-change-list-column-requirement/gr-change-list-column-requirement';
import '../../shared/gr-tooltip-content/gr-tooltip-content';
import {GerritNav} from '../../core/gr-navigation/gr-navigation';
import {getDisplayName} from '../../../utils/display-name-util';
import {getPluginEndpoints} from '../../shared/gr-js-api-interface/gr-plugin-endpoints';
import {getPluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader';
import {getAppContext} from '../../../services/app-context';
import {truncatePath} from '../../../utils/path-list-util';
import {changeStatuses} from '../../../utils/change-util';
import {isSelf, isServiceUser} from '../../../utils/account-util';
import {ReportingService} from '../../../services/gr-reporting/gr-reporting';
import {
  ChangeInfo,
  ServerInfo,
  AccountInfo,
  QuickLabelInfo,
  Timestamp,
} from '../../../types/common';
import {hasOwnProperty} from '../../../utils/common-util';
import {pluralize} from '../../../utils/string-util';
import {showNewSubmitRequirements} from '../../../utils/label-util';
import {changeListStyles} from '../../../styles/gr-change-list-styles';
import {sharedStyles} from '../../../styles/shared-styles';
import {LitElement, css, html} from 'lit';
import {customElement, property, state} from 'lit/decorators';
import {submitRequirementsStyles} from '../../../styles/gr-submit-requirements-styles';
import {ifDefined} from 'lit/directives/if-defined';

enum ChangeSize {
  XS = 10,
  SMALL = 50,
  MEDIUM = 250,
  LARGE = 1000,
}

// export for testing
export enum LabelCategory {
  NOT_APPLICABLE = 'NOT_APPLICABLE',
  APPROVED = 'APPROVED',
  POSITIVE = 'POSITIVE',
  NEUTRAL = 'NEUTRAL',
  UNRESOLVED_COMMENTS = 'UNRESOLVED_COMMENTS',
  NEGATIVE = 'NEGATIVE',
  REJECTED = 'REJECTED',
}

// How many reviewers should be shown with an account-label?
const PRIMARY_REVIEWERS_COUNT = 2;

declare global {
  interface HTMLElementTagNameMap {
    'gr-change-list-item': GrChangeListItem;
  }
}
/**
 * @attr {Boolean} selected - change list item is selected by cursor
 */
@customElement('gr-change-list-item')
export class GrChangeListItem extends LitElement {
  /** The logged-in user's account, or null if no user is logged in. */
  @property({type: Object})
  account: AccountInfo | null = null;

  @property({type: Array})
  visibleChangeTableColumns?: string[];

  @property({type: Array})
  labelNames?: string[];

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

  @property({type: Object})
  config?: ServerInfo;

  /** Name of the section in the change-list. Used for reporting. */
  @property({type: String})
  sectionName?: string;

  @property({type: Boolean})
  showStar = false;

  @property({type: Boolean})
  showNumber = false;

  @state() private dynamicCellEndpoints?: string[];

  reporting: ReportingService = getAppContext().reportingService;

  private readonly flagsService = getAppContext().flagsService;

  override connectedCallback() {
    super.connectedCallback();
    getPluginLoader()
      .awaitPluginsLoaded()
      .then(() => {
        this.dynamicCellEndpoints = getPluginEndpoints().getDynamicEndpoints(
          'change-list-item-cell'
        );
      });
  }

  static override get styles() {
    return [
      changeListStyles,
      sharedStyles,
      submitRequirementsStyles,
      css`
        :host {
          display: table-row;
          color: var(--primary-text-color);
        }
        :host(:focus) {
          outline: none;
        }
        :host(:hover) {
          background-color: var(--hover-background-color);
        }
        .container {
          position: relative;
        }
        .content {
          overflow: hidden;
          position: absolute;
          text-overflow: ellipsis;
          white-space: nowrap;
          width: 100%;
        }
        .content a {
          display: block;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
          width: 100%;
        }
        .comments,
        .reviewers,
        .requirements {
          white-space: nowrap;
        }
        .reviewers {
          --account-max-length: 70px;
        }
        .spacer {
          height: 0;
          overflow: hidden;
        }
        .status {
          align-items: center;
          display: inline-flex;
        }
        .status .comma {
          padding-right: var(--spacing-xs);
        }
        /* Used to hide the leading separator comma for statuses. */
        .status .comma:first-of-type {
          display: none;
        }
        .size gr-tooltip-content {
          margin: -0.4rem -0.6rem;
          max-width: 2.5rem;
          padding: var(--spacing-m) var(--spacing-l);
        }
        .size span {
          border-radius: var(--border-radius);
          color: var(--dashboard-size-text);
          font-size: var(--font-size-small);
          /* To set height and width of span, it has to be inline block */
          display: inline-block;
          height: 20px;
          width: 20px;
          text-align: center;
          vertical-align: top;
        }
        .size span.size-xs {
          background-color: var(--dashboard-size-xs);
          color: var(--dashboard-size-xs-text);
        }
        .size span.size-s {
          background-color: var(--dashboard-size-s);
        }
        .size span.size-m {
          background-color: var(--dashboard-size-m);
        }
        .size span.size-l {
          background-color: var(--dashboard-size-l);
        }
        .size span.size-xl {
          background-color: var(--dashboard-size-xl);
          color: var(--dashboard-size-xl-text);
        }
        a {
          color: inherit;
          cursor: pointer;
          text-decoration: none;
        }
        a:hover {
          text-decoration: underline;
        }
        .subject:hover .content {
          text-decoration: underline;
        }
        .u-monospace {
          font-family: var(--monospace-font-family);
          font-size: var(--font-size-mono);
          line-height: var(--line-height-mono);
        }
        .u-green,
        .u-green iron-icon {
          color: var(--positive-green-text-color);
        }
        .u-red,
        .u-red iron-icon {
          color: var(--negative-red-text-color);
        }
        .u-gray-background {
          background-color: var(--table-header-background-color);
        }
        .comma,
        .placeholder {
          color: var(--deemphasized-text-color);
        }
        .cell.label {
          font-weight: var(--font-weight-normal);
        }
        .cell.label iron-icon {
          vertical-align: top;
        }
        /* Requirement child needs whole area */
        .cell.requirement {
          padding: 0;
          margin: 0;
        }
        @media only screen and (max-width: 50em) {
          :host {
            display: flex;
          }
        }
      `,
    ];
  }

  override render() {
    const changeUrl = this.computeChangeURL();
    return html`
      <td aria-hidden="true" class="cell leftPadding"></td>
      ${this.renderCellStar()} ${this.renderCellNumber(changeUrl)}
      ${this.renderCellSubject(changeUrl)} ${this.renderCellStatus()}
      ${this.renderCellOwner()} ${this.renderCellReviewers()}
      ${this.renderCellComments()} ${this.renderCellRepo()}
      ${this.renderCellBranch()} ${this.renderCellUpdated()}
      ${this.renderCellSubmitted()} ${this.renderCellWaiting()}
      ${this.renderCellSize()} ${this.renderCellRequirements()}
      ${this.labelNames?.map(labelNames => this.renderChangeLabels(labelNames))}
      ${this.dynamicCellEndpoints?.map(pluginEndpointName =>
        this.renderChangePluginEndpoint(pluginEndpointName)
      )}
    `;
  }

  private renderCellStar() {
    if (!this.showStar) return;

    return html`
      <td class="cell star">
        <gr-change-star .change=${this.change}></gr-change-star>
      </td>
    `;
  }

  private renderCellNumber(changeUrl: string) {
    if (!this.showNumber) return;

    return html`
      <td class="cell number">
        <a href="${changeUrl}">${this.change?._number}</a>
      </td>
    `;
  }

  private renderCellSubject(changeUrl: string) {
    if (this.computeIsColumnHidden('Subject', this.visibleChangeTableColumns))
      return;

    return html`
      <td class="cell subject">
        <a
          title="${ifDefined(this.change?.subject)}"
          href="${changeUrl}"
          @click=${() => this.handleChangeClick()}
        >
          <div class="container">
            <div class="content">${this.change?.subject}</div>
            <div class="spacer">${this.change?.subject}</div>
            <span>&nbsp;</span>
          </div>
        </a>
      </td>
    `;
  }

  private renderCellStatus() {
    if (this.computeIsColumnHidden('Status', this.visibleChangeTableColumns))
      return;

    return html` <td class="cell status">${this.renderChangeStatus()}</td> `;
  }

  private renderChangeStatus() {
    if (!this.changeStatuses().length) {
      return html`<span class="placeholder">--</span>`;
    }

    return this.changeStatuses().map(
      status => html`
        <div class="comma">,</div>
        <gr-change-status flat .status=${status}></gr-change-status>
      `
    );
  }

  private renderCellOwner() {
    if (this.computeIsColumnHidden('Owner', this.visibleChangeTableColumns))
      return;

    return html`
      <td class="cell owner">
        <gr-account-link
          highlightAttention
          .change=${this.change}
          .account=${this.change?.owner}
        ></gr-account-link>
      </td>
    `;
  }

  private renderCellReviewers() {
    if (this.computeIsColumnHidden('Reviewers', this.visibleChangeTableColumns))
      return;

    return html`
      <td class="cell reviewers">
        <div>
          ${this.computePrimaryReviewers().map((reviewer, index) =>
            this.renderChangeReviewers(reviewer, index)
          )}
          ${this.computeAdditionalReviewersCount()
            ? html`<span title="${this.computeAdditionalReviewersTitle()}"
                >+${this.computeAdditionalReviewersCount()}</span
              >`
            : ''}
        </div>
      </td>
    `;
  }

  private renderChangeReviewers(reviewer: AccountInfo, index: number) {
    return html`
      <gr-account-link
        hideAvatar
        firstName
        highlightAttention
        .change=${this.change}
        .account=${reviewer}
      ></gr-account-link
      ><span ?hidden=${this.computeCommaHidden(index)} aria-hidden="true"
        >,
      </span>
    `;
  }

  private renderCellComments() {
    if (this.computeIsColumnHidden('Comments', this.visibleChangeTableColumns))
      return;

    return html`
      <td class="cell comments">
        ${this.change?.unresolved_comment_count
          ? html`<iron-icon icon="gr-icons:comment"></iron-icon>`
          : ''}
        <span
          >${this.computeComments(this.change?.unresolved_comment_count)}</span
        >
      </td>
    `;
  }

  private renderCellRepo() {
    if (this.computeIsColumnHidden('Repo', this.visibleChangeTableColumns))
      return;

    return html`
      <td class="cell repo">
        <a class="fullRepo" href="${this.computeRepoUrl()}">
          ${this.computeRepoDisplay()}
        </a>
        <a
          class="truncatedRepo"
          href="${this.computeRepoUrl()}"
          title="${this.computeRepoDisplay()}"
        >
          ${this.computeTruncatedRepoDisplay()}
        </a>
      </td>
    `;
  }

  private renderCellBranch() {
    if (this.computeIsColumnHidden('Branch', this.visibleChangeTableColumns))
      return;

    return html`
      <td class="cell branch">
        <a href="${this.computeRepoBranchURL()}"> ${this.change?.branch} </a>
        ${this.renderChangeBranch()}
      </td>
    `;
  }

  private renderChangeBranch() {
    if (!this.change?.topic) return;

    return html`
      (<a href="${this.computeTopicURL()}"
        ><!--
      --><gr-limited-text .limit=${50} .text=${this.change.topic}>
        </gr-limited-text
        ><!--
    --></a
      >)
    `;
  }

  private renderCellUpdated() {
    if (this.computeIsColumnHidden('Updated', this.visibleChangeTableColumns))
      return;

    return html`
      <td class="cell updated">
        <gr-date-formatter
          withTooltip
          .dateStr=${this.formatDate(this.change?.updated)}
        ></gr-date-formatter>
      </td>
    `;
  }

  private renderCellSubmitted() {
    if (this.computeIsColumnHidden('Submitted', this.visibleChangeTableColumns))
      return;

    return html`
      <td class="cell submitted">
        <gr-date-formatter
          withTooltip
          .dateStr=${this.formatDate(this.change?.submitted)}
        ></gr-date-formatter>
      </td>
    `;
  }

  private renderCellWaiting() {
    if (this.computeIsColumnHidden('Waiting', this.visibleChangeTableColumns))
      return;

    return html`
      <td class="cell waiting">
        <gr-date-formatter
          withTooltip
          forceRelative
          relativeOptionNoAgo
          .dateStr=${this.computeWaiting()}
        ></gr-date-formatter>
      </td>
    `;
  }

  private renderCellSize() {
    if (this.computeIsColumnHidden('Size', this.visibleChangeTableColumns))
      return;

    return html`
      <td class="cell size">
        <gr-tooltip-content has-tooltip title="${this.computeSizeTooltip()}">
          ${this.renderChangeSize()}
        </gr-tooltip-content>
      </td>
    `;
  }

  private renderChangeSize() {
    const changeSize = this.computeChangeSize();
    if (!changeSize) return html`<span class="placeholder">--</span>`;

    return html`
      <span class="size-${changeSize.toLowerCase()}">${changeSize}</span>
    `;
  }

  private renderCellRequirements() {
    if (this.computeIsColumnHidden(' Status ', this.visibleChangeTableColumns))
      return;

    return html`
      <td class="cell requirements">
        <gr-change-list-column-requirements-summary .change=${this.change}>
        </gr-change-list-column-requirements-summary>
      </td>
    `;
  }

  private renderChangeLabels(labelName: string) {
    if (showNewSubmitRequirements(this.flagsService, this.change)) {
      return html` <td class="cell label requirement">
        <gr-change-list-column-requirement
          .change=${this.change}
          .labelName=${labelName}
        >
        </gr-change-list-column-requirement>
      </td>`;
    }
    return html`
      <td
        title="${this.computeLabelTitle(labelName)}"
        class="${this.computeLabelClass(labelName)}"
      >
        ${this.renderChangeHasLabelIcon(labelName)}
      </td>
    `;
  }

  private renderChangeHasLabelIcon(labelName: string) {
    if (this.computeLabelIcon(labelName) === '')
      return html`<span>${this.computeLabelValue(labelName)}</span>`;

    return html`
      <iron-icon icon=${this.computeLabelIcon(labelName)}></iron-icon>
    `;
  }

  private renderChangePluginEndpoint(pluginEndpointName: string) {
    return html`
      <td class="cell endpoint">
        <gr-endpoint-decorator name="${pluginEndpointName}">
          <gr-endpoint-param name="change" .value=${this.change}>
          </gr-endpoint-param>
        </gr-endpoint-decorator>
      </td>
    `;
  }

  private changeStatuses() {
    if (!this.change) return [];
    return changeStatuses(this.change);
  }

  private computeChangeURL() {
    if (!this.change) return '';
    return GerritNav.getUrlForChange(this.change);
  }

  // private but used in test
  computeLabelTitle(labelName: string) {
    const label: QuickLabelInfo | undefined = this.change?.labels?.[labelName];
    const category = this.computeLabelCategory(labelName);
    if (!label || category === LabelCategory.NOT_APPLICABLE) {
      return 'Label not applicable';
    }
    const titleParts: string[] = [];
    if (category === LabelCategory.UNRESOLVED_COMMENTS) {
      const num = this.change?.unresolved_comment_count ?? 0;
      titleParts.push(pluralize(num, 'unresolved comment'));
    }
    const significantLabel =
      label.rejected || label.approved || label.disliked || label.recommended;
    if (significantLabel?.name) {
      titleParts.push(`${labelName} by ${significantLabel.name}`);
    }
    if (titleParts.length > 0) {
      return titleParts.join(',\n');
    }
    return labelName;
  }

  // private but used in test
  computeLabelClass(labelName: string) {
    const classes = ['cell', 'label'];
    const category = this.computeLabelCategory(labelName);
    switch (category) {
      case LabelCategory.NOT_APPLICABLE:
        classes.push('u-gray-background');
        break;
      case LabelCategory.APPROVED:
        classes.push('u-green');
        break;
      case LabelCategory.POSITIVE:
        classes.push('u-monospace');
        classes.push('u-green');
        break;
      case LabelCategory.NEGATIVE:
        classes.push('u-monospace');
        classes.push('u-red');
        break;
      case LabelCategory.REJECTED:
        classes.push('u-red');
        break;
    }
    return classes.sort().join(' ');
  }

  // private but used in test
  computeLabelIcon(labelName: string): string {
    const category = this.computeLabelCategory(labelName);
    switch (category) {
      case LabelCategory.APPROVED:
        return 'gr-icons:check';
      case LabelCategory.UNRESOLVED_COMMENTS:
        return 'gr-icons:comment';
      case LabelCategory.REJECTED:
        return 'gr-icons:close';
      default:
        return '';
    }
  }

  // private but used in test
  computeLabelCategory(labelName: string) {
    const label: QuickLabelInfo | undefined = this.change?.labels?.[labelName];
    if (!label) {
      return LabelCategory.NOT_APPLICABLE;
    }
    if (label.rejected) {
      return LabelCategory.REJECTED;
    }
    if (label.value && label.value < 0) {
      return LabelCategory.NEGATIVE;
    }
    if (this.change?.unresolved_comment_count && labelName === 'Code-Review') {
      return LabelCategory.UNRESOLVED_COMMENTS;
    }
    if (label.approved) {
      return LabelCategory.APPROVED;
    }
    if (label.value && label.value > 0) {
      return LabelCategory.POSITIVE;
    }
    return LabelCategory.NEUTRAL;
  }

  // private but used in test
  computeLabelValue(labelName: string) {
    const label: QuickLabelInfo | undefined = this.change?.labels?.[labelName];
    const category = this.computeLabelCategory(labelName);
    switch (category) {
      case LabelCategory.NOT_APPLICABLE:
        return '';
      case LabelCategory.APPROVED:
        return '\u2713'; // ✓
      case LabelCategory.POSITIVE:
        return `+${label?.value}`;
      case LabelCategory.NEUTRAL:
        return '';
      case LabelCategory.UNRESOLVED_COMMENTS:
        return 'u';
      case LabelCategory.NEGATIVE:
        return `${label?.value}`;
      case LabelCategory.REJECTED:
        return '\u2715'; // ✕
      default:
        return '';
    }
  }

  private computeRepoUrl() {
    if (!this.change) return '';
    return GerritNav.getUrlForProjectChanges(
      this.change.project,
      true,
      this.change.internalHost
    );
  }

  private computeRepoBranchURL() {
    if (!this.change) return '';
    return GerritNav.getUrlForBranch(
      this.change.branch,
      this.change.project,
      undefined,
      this.change.internalHost
    );
  }

  private computeTopicURL() {
    if (!this.change?.topic) return '';
    return GerritNav.getUrlForTopic(
      this.change.topic,
      this.change.internalHost
    );
  }

  /**
   * Computes the display string for the project column. If there is a host
   * specified in the change detail, the string will be prefixed with it.
   *
   * @param truncate whether or not the project name should be
   * truncated. If this value is truthy, the name will be truncated.
   *
   * private but used in test
   */
  computeRepoDisplay() {
    if (!this.change?.project) return '';
    let str = '';
    if (this.change.internalHost) {
      str += this.change.internalHost + '/';
    }
    str += this.change.project;
    return str;
  }

  // private but used in test
  computeTruncatedRepoDisplay() {
    if (!this.change?.project) {
      return '';
    }
    let str = '';
    if (this.change.internalHost) {
      str += this.change.internalHost + '/';
    }
    str += truncatePath(this.change.project, 2);
    return str;
  }

  // private but used in test
  computeSizeTooltip() {
    if (
      !this.change ||
      this.change.insertions + this.change.deletions === 0 ||
      isNaN(this.change.insertions + this.change.deletions)
    ) {
      return 'Size unknown';
    } else {
      return `added ${this.change.insertions}, removed ${this.change.deletions} lines`;
    }
  }

  private hasAttention(account: AccountInfo) {
    if (!this.change || !this.change.attention_set || !account._account_id) {
      return false;
    }
    return hasOwnProperty(this.change.attention_set, account._account_id);
  }

  /**
   * Computes the array of all reviewers with sorting the reviewers in the
   * attention set before others, and the current user first.
   *
   * private but used in test
   */
  computeReviewers() {
    if (!this.change?.reviewers || !this.change?.reviewers.REVIEWER) return [];
    const reviewers = [...this.change.reviewers.REVIEWER].filter(
      r =>
        (!this.change?.owner ||
          this.change?.owner._account_id !== r._account_id) &&
        !isServiceUser(r)
    );
    reviewers.sort((r1, r2) => {
      if (this.account) {
        if (isSelf(r1, this.account)) return -1;
        if (isSelf(r2, this.account)) return 1;
      }
      if (this.hasAttention(r1) && !this.hasAttention(r2)) return -1;
      if (this.hasAttention(r2) && !this.hasAttention(r1)) return 1;
      return (r1.name || '').localeCompare(r2.name || '');
    });
    return reviewers;
  }

  private computePrimaryReviewers() {
    return this.computeReviewers().slice(0, PRIMARY_REVIEWERS_COUNT);
  }

  private computeAdditionalReviewers() {
    return this.computeReviewers().slice(PRIMARY_REVIEWERS_COUNT);
  }

  private computeAdditionalReviewersCount() {
    return this.computeAdditionalReviewers().length;
  }

  private computeAdditionalReviewersTitle() {
    if (!this.change || !this.config) return '';
    return this.computeAdditionalReviewers()
      .map(user => getDisplayName(this.config, user, true))
      .join(', ');
  }

  private computeComments(unresolved_comment_count?: number) {
    if (!unresolved_comment_count || unresolved_comment_count < 1) return '';
    return `${unresolved_comment_count} unresolved`;
  }

  /**
   * TShirt sizing is based on the following paper:
   * http://dirkriehle.com/wp-content/uploads/2008/09/hicss-42-csdistr-final-web.pdf
   *
   * private but used in test
   */
  computeChangeSize() {
    if (!this.change) return null;
    const delta = this.change.insertions + this.change.deletions;
    if (isNaN(delta) || delta === 0) {
      return null; // Unknown
    }
    if (delta < ChangeSize.XS) {
      return 'XS';
    } else if (delta < ChangeSize.SMALL) {
      return 'S';
    } else if (delta < ChangeSize.MEDIUM) {
      return 'M';
    } else if (delta < ChangeSize.LARGE) {
      return 'L';
    } else {
      return 'XL';
    }
  }

  private computeWaiting(): Timestamp | undefined {
    if (!this.account?._account_id || !this.change?.attention_set)
      return undefined;
    return this.change?.attention_set[this.account._account_id]?.last_update;
  }

  private computeIsColumnHidden(
    columnToCheck?: string,
    columnsToDisplay?: string[]
  ) {
    if (!columnsToDisplay || !columnToCheck) {
      return false;
    }
    return !columnsToDisplay.includes(columnToCheck);
  }

  private formatDate(date: Timestamp | undefined): string | undefined {
    if (!date) return undefined;
    return date.toString();
  }

  private handleChangeClick() {
    // Don't prevent the default and neither stop bubbling. We just want to
    // report the click, but then let the browser handle the click on the link.

    const selfId = (this.account && this.account._account_id) || -1;
    const ownerId =
      (this.change && this.change.owner && this.change.owner._account_id) || -1;

    this.reporting.reportInteraction('change-row-clicked', {
      section: this.sectionName,
      isOwner: selfId === ownerId,
    });
  }

  private computeCommaHidden(index: number) {
    const additionalCount = this.computeAdditionalReviewersCount();
    const primaryCount = this.computePrimaryReviewers().length;
    const isLast = index === primaryCount - 1;
    return isLast && additionalCount === 0;
  }
}
