/**
 * @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 {AccountId, GroupId} from '@gerritcodereview/typescript-api/rest-api';
import {CodeOwnerInfo, CodeOwnersInfo, FetchedFile} from './code-owners-api';
import {BestSuggestionsLimit} from './code-owners-model';

export interface GroupedFiles {
  groupName: {name: string|undefined; prefix: string;};
  files: Array<FetchedFile>;
  owners?: CodeOwnersInfo;
  error?: Error;
  hasSelected?: boolean;
  expanded?: boolean;
}

/**
 * For each file calculates owners to display and group all files by those
 * owners. The function creates "fake" groups when one or more
 * reviewers are included in all owners of a file, but none of reviewers is
 * included in best reviewers for the file.
 *
 * Such situations are possible when user turns on "Show all owners", selects
 * one of newly displayed owners and then turns off "Show all owners". Without
 * "fake" groups a user can see inconsistent state in dialog.
 */
export function getDisplayOwnersGroups(
    files: Array<FetchedFile>,
    allOwnersByPathMap: Map<string, CodeOwnersInfo|undefined>,
    reviewersIdSet: Set<AccountId|GroupId>,
    allowAllOwnersSubstition: boolean): Array<GroupedFiles> {
  const getDisplayOwnersFunc = !allowAllOwnersSubstition ||
          allOwnersByPathMap.size === 0 || reviewersIdSet.size === 0 ?
      (file: FetchedFile) => file.info.owners :
      (file: FetchedFile) =>
          getDisplayOwners(file, allOwnersByPathMap, reviewersIdSet);
  return groupFilesByOwners(files, getDisplayOwnersFunc);
}

function getDisplayOwners(
    file: FetchedFile,
    allOwnersByPathMap: Map<String, CodeOwnersInfo|undefined>,
    reviewersIdSet: Set<AccountId|GroupId>) {
  const ownerSelected = (owner: CodeOwnerInfo) =>
      owner?.account?._account_id !== undefined &&
      reviewersIdSet.has(owner.account._account_id);
  const defaultOwners = file.info.owners;
  if (!defaultOwners || defaultOwners.owned_by_all_users ||
      defaultOwners.code_owners.some(ownerSelected)) {
    return defaultOwners;
  }
  const allOwners = allOwnersByPathMap.get(file.path);
  if (!allOwners) return defaultOwners;
  if (allOwners.owned_by_all_users) return allOwners;
  const selectedAllOwners = allOwners.code_owners.filter(ownerSelected);
  if (selectedAllOwners.length === 0) return defaultOwners;
  return {
    code_owners: selectedAllOwners.slice(0, BestSuggestionsLimit),
  };
}

function groupFilesByOwners(
    files: Array<FetchedFile>,
    getDisplayOwnersFunc: (file: FetchedFile) =>
        CodeOwnersInfo | undefined): Array<GroupedFiles> {
  // Note: for renamed or moved files, they will have two entries in the map
  // we will treat them as two entries when group as well
  const ownersFilesMap =
      new Map<string, {files: Array<FetchedFile>, owners: CodeOwnersInfo}>();
  const failedToFetchFiles = new Set<FetchedFile>();
  for (const file of files) {
    // for files failed to fetch, add them to the special group
    if (file.info.error) {
      failedToFetchFiles.add(file);
      continue;
    }

    // do not include files still in fetching
    if (!file.info.owners) {
      continue;
    }
    const displayOwners = getDisplayOwnersFunc(file);
    if (displayOwners === undefined) continue;

    const ownersKey = getOwnersGroupKey(displayOwners);
    ownersFilesMap.set(
        ownersKey,
        ownersFilesMap.get(ownersKey) ?? {files: [], owners: displayOwners});
    ownersFilesMap.get(ownersKey)!.files.push(file);
  }
  const groupedItems = [];
  for (const ownersKey of ownersFilesMap.keys()) {
    const groupName = getGroupName(ownersFilesMap.get(ownersKey)!.files);
    groupedItems.push({
      groupName,
      files: ownersFilesMap.get(ownersKey)!.files,
      owners: ownersFilesMap.get(ownersKey)!.owners,
    });
  }

  if (failedToFetchFiles.size > 0) {
    const failedFiles = [...failedToFetchFiles];
    groupedItems.push({
      groupName: getGroupName(failedFiles),
      files: failedFiles,
      error: new Error(
          'Failed to fetch code owner info. Try to refresh the page.'),
    });
  }
  return groupedItems;
}

function getOwnersGroupKey(owners: CodeOwnersInfo) {
  if (owners.owned_by_all_users) {
    return '__owned_by_all_users__';
  }
  const code_owners = owners.code_owners;
  return code_owners.map(owner => owner.account?._account_id).sort().join(',');
}

function getGroupName(files: Array<FetchedFile>) {
  const path = files[0].path.split('/');
  const fileName = path.pop();
  const shortenedDirectory = path.map(d => d.charAt(0)).join('/');
  return {
    name: `${shortenedDirectory}/${fileName}`,
    prefix: files.length > 1 ? `+ ${files.length - 1} more` : '',
  };
}
