/**
 * @license
 * Copyright 2019 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {
  getAccountDisplayName,
  getGroupDisplayName,
} from '../../utils/display-name-util';
import {RestApiService} from '../gr-rest-api/gr-rest-api';
import {
  AccountInfo,
  isReviewerAccountSuggestion,
  isReviewerGroupSuggestion,
  NumericChangeId,
  ServerInfo,
  SuggestedReviewerInfo,
  Suggestion,
} from '../../types/common';
import {assertNever} from '../../utils/common-util';
import {AutocompleteSuggestion} from '../../elements/shared/gr-autocomplete/gr-autocomplete';
import {allSettled, isFulfilled} from '../../utils/async-util';
import {isDefined, ParsedChangeInfo} from '../../types/types';
import {accountKey} from '../../utils/account-util';
import {
  AccountId,
  ChangeInfo,
  EmailAddress,
  GroupId,
  ReviewerState,
} from '../../api/rest-api';
import {throwingErrorCallback} from '../../elements/shared/gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper';

export interface ReviewerSuggestionsProvider {
  getSuggestions(input: string): Promise<Suggestion[]>;
  makeSuggestionItem(
    suggestion: Suggestion
  ): AutocompleteSuggestion<SuggestedReviewerInfo>;
}

export class GrReviewerSuggestionsProvider
  implements ReviewerSuggestionsProvider
{
  private changes: (ChangeInfo | ParsedChangeInfo)[];

  constructor(
    private restApi: RestApiService,
    private type: ReviewerState.REVIEWER | ReviewerState.CC,
    private config: ServerInfo | undefined,
    private loggedIn: boolean,
    ...changes: (ChangeInfo | ParsedChangeInfo)[]
  ) {
    this.changes = changes;
  }

  /**
   * Requests related suggestions.
   *
   * If the request fails the returned promise is rejected.
   */
  async getSuggestions(input: string): Promise<Suggestion[]> {
    if (!this.loggedIn) return [];

    const resultsByChangeIndex = await allSettled(
      this.changes.map(change =>
        this.getSuggestionsForChange(change._number, input)
      )
    );
    const suggestionsByChangeIndex = resultsByChangeIndex
      .filter(isFulfilled)
      .map(result => result.value)
      .filter(isDefined);
    if (suggestionsByChangeIndex.length !== resultsByChangeIndex.length) {
      // one of the requests failed, so don't allow any suggestions.
      return [];
    }

    // Pass the union of all the suggestions through each change, keeping only
    // suggestions where either:
    //   A) the change had the suggestion too, or
    //   B) the suggestion is already a reviewer/CC on the change (depending on
    //      this.type).
    return this.changes.reduce((suggestions, change, changeIndex) => {
      const reviewerAndSuggestionKeys = new Set<
        AccountId | EmailAddress | GroupId | undefined
      >([
        ...(change.reviewers[this.type]?.map(accountKey) ?? []),
        ...suggestionsByChangeIndex[changeIndex].map(suggestionKey),
      ]);
      return suggestions.filter(suggestion =>
        reviewerAndSuggestionKeys.has(suggestionKey(suggestion))
      );
    }, uniqueSuggestions(suggestionsByChangeIndex.flat()));
  }

  makeSuggestionItem(
    suggestion: Suggestion
  ): AutocompleteSuggestion<SuggestedReviewerInfo> {
    if (isReviewerAccountSuggestion(suggestion)) {
      // Reviewer is an account suggestion from getChangeSuggestedReviewers.
      return {
        name: getAccountDisplayName(this.config, suggestion.account),
        value: suggestion,
      };
    }

    if (isReviewerGroupSuggestion(suggestion)) {
      // Reviewer is a group suggestion from getChangeSuggestedReviewers.
      return {
        name: getGroupDisplayName(suggestion.group),
        value: suggestion,
      };
    }

    if (isAccountSuggestion(suggestion)) {
      // Reviewer is an account suggestion from getSuggestedAccounts.
      return {
        name: getAccountDisplayName(this.config, suggestion),
        value: {account: suggestion, count: 1},
      };
    }
    assertNever(suggestion, 'Received an incorrect suggestion');
  }

  private getSuggestionsForChange(
    changeNumber: NumericChangeId,
    input: string
  ): Promise<SuggestedReviewerInfo[] | undefined> {
    return this.type === ReviewerState.REVIEWER
      ? this.restApi.getChangeSuggestedReviewers(
          changeNumber,
          input,
          throwingErrorCallback
        )
      : this.restApi.getChangeSuggestedCCs(
          changeNumber,
          input,
          throwingErrorCallback
        );
  }
}

function uniqueSuggestions(suggestions: Suggestion[]): Suggestion[] {
  return suggestions.filter(
    (suggestion, index) =>
      index ===
      suggestions.findIndex(
        other => suggestionKey(suggestion) === suggestionKey(other)
      )
  );
}

function suggestionKey(suggestion: Suggestion) {
  if (isReviewerAccountSuggestion(suggestion)) {
    return accountKey(suggestion.account);
  } else if (isReviewerGroupSuggestion(suggestion)) {
    return suggestion.group.id;
  } else if (isAccountSuggestion(suggestion)) {
    return accountKey(suggestion);
  }
  return undefined;
}

function isAccountSuggestion(s: Suggestion): s is AccountInfo {
  return (s as AccountInfo)._account_id !== undefined;
}
