/**
 * @license
 * Copyright (C) 2020 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.
 */

/**
 * All statuses returned for owner status.
 *
 * @enum
 */
export const OwnerStatus = {
  INSUFFICIENT_REVIEWERS: 'INSUFFICIENT_REVIEWERS',
  PENDING: 'PENDING',
  APPROVED: 'APPROVED',
};

/**
 * @enum
 */
const FetchStatus = {
  NOT_STARTED: 0,
  FETCHING: 1,
  FINISHED: 2,
  ABORT: 3,
};

/**
 * Specifies status for a change. The same as ChangeStatus enum in gerrit
 *
 * @enum
 */
const ChangeStatus = {
  ABANDONED: 'ABANDONED',
  MERGED: 'MERGED',
  NEW: 'NEW',
};

/**
 * @enum
 */
const UserRole = {
  ANONYMOUS: 'ANONYMOUS',
  AUTHOR: 'AUTHOR',
  CHANGE_OWNER: 'CHANGE_OWNER',
  REVIEWER: 'REVIEWER',
  CC: 'CC',
  REMOVED_REVIEWER: 'REMOVED_REVIEWER',
  OTHER: 'OTHER',
};

/**
 * Responsible for communicating with the rest-api
 *
 * @see resources/Documentation/rest-api.md
 */
class CodeOwnerApi {
  constructor(restApi) {
    this.restApi = restApi;
  }

  /**
   * Returns a promise fetching the owner statuses for all files within the change.
   *
   * @doc https://gerrit.googlesource.com/plugins/code-owners/+/refs/heads/master/resources/Documentation/rest-api.md#change-endpoints
   * @param {string} changeId
   */
  listOwnerStatus(changeId) {
    return this.restApi.get(`/changes/${changeId}/code_owners.status`);
  }

  /**
   * Returns a promise fetching the owners for a given path.
   *
   * @doc https://gerrit.googlesource.com/plugins/code-owners/+/refs/heads/master/resources/Documentation/rest-api.md#list-code-owners-for-path-in-branch
   * @param {string} changeId
   * @param {string} path
   */
  listOwnersForPath(changeId, path) {
    return this.restApi.get(
        `/changes/${changeId}/revisions/current/code_owners` +
        `/${encodeURIComponent(path)}?limit=5&o=DETAILS`
    );
  }

  /**
   * Returns a promise fetching the owners config for a given path.
   *
   * @doc https://gerrit.googlesource.com/plugins/code-owners/+/refs/heads/master/resources/Documentation/rest-api.md#branch-endpoints
   * @param {string} project
   * @param {string} branch
   * @param {string} path
   */
  getConfigForPath(project, branch, path) {
    return this.restApi.get(
        `/projects/${encodeURIComponent(project)}/` +
        `branches/${encodeURIComponent(branch)}/` +
        `code_owners.config/${encodeURIComponent(path)}`
    );
  }

  /**
   * Returns a promise fetching the owners config for a given branch.
   *
   * @doc https://gerrit.googlesource.com/plugins/code-owners/+/refs/heads/master/resources/Documentation/rest-api.md#branch-endpoints
   * @param {string} project
   * @param {string} branch
   */
  getBranchConfig(project, branch) {
    return this.restApi.get(
        `/projects/${encodeURIComponent(project)}/` +
        `branches/${encodeURIComponent(branch)}/` +
        `code_owners.branch_config`
    );
  }
}

/**
 * Wrapper around codeOwnerApi, sends each requests only once and then cache
 * the response. A new CodeOwnersCacheApi instance is created every time when a
 * new change object is assigned.
 * Gerrit never updates existing change object, but instead always assigns a new
 * change object. Particularly, a new change object is assigned when a change
 * is updated and user clicks reload toasts to see the updated change.
 * As a result, the lifetime of a cache is the same as a lifetime of an assigned
 * change object.
 * Periodical cache invalidation can lead to inconsistency in UI, i.e.
 * user can see the old reviewers list (reflects a state when a change was
 * loaded) and code-owners status for the current reviewer list. To avoid
 * this incostistency, the cache doesn't invalidated.
 */
export class CodeOwnersCacheApi {
  constructor(codeOwnerApi, change) {
    this.codeOwnerApi = codeOwnerApi;
    this.change = change;
    this.promises = {};
  }

  _fetchOnce(cacheKey, asyncFn) {
    if (!this.promises[cacheKey]) {
      this.promises[cacheKey] = asyncFn();
    }
    return this.promises[cacheKey];
  }

  getAccount() {
    return this._fetchOnce('getAccount', () => this._getAccount());
  }

  async _getAccount() {
    const loggedIn = await this.codeOwnerApi.restApi.getLoggedIn();
    if (!loggedIn) return undefined;
    return await this.codeOwnerApi.restApi.getAccount();
  }

  listOwnerStatus() {
    return this._fetchOnce('listOwnerStatus',
        () => this.codeOwnerApi.listOwnerStatus(this.change._number));
  }

  getBranchConfig() {
    return this._fetchOnce('getBranchConfig',
        () => this.codeOwnerApi.getBranchConfig(this.change.project,
            this.change.branch));
  }

  listOwnersForPath(path) {
    return this._fetchOnce(`listOwnersForPath:${path}`,
        () => this.codeOwnerApi.listOwnersForPath(this.change.id, path));
  }
}

/**
 * Service for the data layer used in the plugin UI.
 */
export class CodeOwnerService {
  constructor(restApi, change, options = {}) {
    this.restApi = restApi;
    this.change = change;
    this.options = {maxConcurrentRequests: 10, ...options};
    const codeOwnerApi = new CodeOwnerApi(restApi);
    this.codeOwnerCacheApi = new CodeOwnersCacheApi(codeOwnerApi, change);

    // fetched files and fetching status
    this._fetchedOwners = new Map();
    this._fetchStatus = FetchStatus.NOT_STARTED;
    this._totalFetchCount = 0;
  }

  /**
   * Prefetch data
   */
  async prefetch() {
    this.codeOwnerCacheApi.getAccount();
    this.getStatus();
  }

  /**
   * Returns the role of the current user. The returned value reflects the
   * role of the user at the time when the change is loaded.
   * For example, if a user removes themselves as a reviewer, the returned
   * role 'REVIEWER' remains unchanged until the change view is reloaded.
   */
  async getLoggedInUserInitialRole() {
    const account = await this.codeOwnerCacheApi.getAccount();
    if (!account) {
      return UserRole.ANONYMOUS;
    }
    const change = this.change;
    if (
      change.revisions &&
      change.current_revision &&
      change.revisions[change.current_revision]
    ) {
      const commit = change.revisions[change.current_revision].commit;
      if (
        commit &&
        commit.author &&
        account.email &&
        commit.author.email === account.email
      ) {
        return UserRole.AUTHOR;
      }
    }
    if (change.owner._account_id === account._account_id) {
      return UserRole.CHANGE_OWNER;
    }
    if (change.reviewers) {
      if (this._accountInReviewers(change.reviewers.REVIEWER, account)) {
        return UserRole.REVIEWER;
      } else if (this._accountInReviewers(change.reviewers.CC, account)) {
        return UserRole.CC;
      } else if (this._accountInReviewers(change.reviewers.REMOVED, account)) {
        return UserRole.REMOVED_REVIEWER;
      }
    }
    return UserRole.OTHER;
  }

  _accountInReviewers(reviewers, account) {
    if (!reviewers) {
      return false;
    }
    return reviewers.some(reviewer =>
      reviewer._account_id === account._account_id);
  }

  async getStatus() {
    const status = await this._getStatus();
    if (status.enabled && !this.isOnLatestPatchset(status.patchsetNumber)) {
      // status is outdated, abort and re-init
      this.abort();
      this.prefetch();
      return await this.codeOwnerCacheApi.getStatus();
    }
    return status;
  }

  async _getStatus() {
    const enabled = await this.isCodeOwnerEnabled();
    if (!enabled) {
      return {
        patchsetNumber: 0,
        enabled: false,
        codeOwnerStatusMap: new Map(),
        rawStatuses: [],
      };
    }

    const onwerStatus = await this.codeOwnerCacheApi.listOwnerStatus();

    return {
      enabled: true,
      patchsetNumber: onwerStatus.patch_set_number,
      codeOwnerStatusMap: this._formatStatuses(
          onwerStatus.file_code_owner_statuses
      ),
      rawStatuses: onwerStatus.file_code_owner_statuses,
    };
  }

  async areAllFilesApproved() {
    const {rawStatuses} = await this.getStatus();
    return !rawStatuses.some(status => {
      const oldPathStatus = status.old_path_status;
      const newPathStatus = status.new_path_status;
      // For deleted files, no new_path_status exists
      return (newPathStatus && newPathStatus.status !== OwnerStatus.APPROVED)
        || (oldPathStatus && oldPathStatus.status !== OwnerStatus.APPROVED);
    });
  }

  /**
   * Gets owner suggestions.
   *
   * @returns {{
   *  finished?: boolean,
   *  progress?: string,
   *  suggestions: Array<{
   *    groupName: {
   *      name: string,
   *      prefix: string
   *    },
   *    error?: Error,
   *    owners?: Array,
   *    files: Array,
   *  }>
   * }}
   */
  async getSuggestedOwners() {
    // In case its aborted due to outdated patches
    // should kick start the fetching again
    // Note: we currently are not reusing the instance when switching changes,
    // so if its `abort` due to different changes, the whole instance will be
    // outdated and not used.
    if (this._fetchStatus === FetchStatus.NOT_STARTED
      || this._fetchStatus === FetchStatus.ABORT) {
      await this._fetchSuggestedOwners();
      this._fetchStatus = FetchStatus.FINISHED;
    }

    const {codeOwnerStatusMap} = await this.getStatus();
    return {
      finished: this._fetchStatus === FetchStatus.FINISHED,
      status: this._fetchStatus,
      progress: this._totalFetchCount === 0 ?
        `Loading suggested owners ...` :
        `${this._fetchedOwners.size} out of ${this._totalFetchCount} ` +
          `files have returned suggested owners.`,
      suggestions: this._groupFilesByOwners(codeOwnerStatusMap),
    };
  }

  async _fetchSuggestedOwners() {
    // reset existing temporary storage
    this._fetchedOwners = new Map();
    this._fetchStatus = FetchStatus.FETCHING;
    this._totalFetchCount = 0;

    const {codeOwnerStatusMap} = await this.getStatus();
    // only fetch those not approved yet
    const filesGroupByStatus = [...codeOwnerStatusMap.keys()].reduce(
        (list, file) => {
          const status = codeOwnerStatusMap
              .get(file).status;
          if (status === OwnerStatus.INSUFFICIENT_REVIEWERS) {
            list.missing.push(file);
          } else if (status === OwnerStatus.PENDING) {
            list.pending.push(file);
          }
          return list;
        }
        , {pending: [], missing: []});
    // always fetch INSUFFICIENT_REVIEWERS first and then pending
    const filesToFetch = filesGroupByStatus.missing
        .concat(filesGroupByStatus.pending);
    this._totalFetchCount = filesToFetch.length;
    return await this._batchFetchCodeOwners(filesToFetch);
  }

  _formatStatuses(statuses) {
    // convert the array of statuses to map between file path -> status
    return statuses.reduce((prev, cur) => {
      const newPathStatus = cur.new_path_status;
      const oldPathStatus = cur.old_path_status;
      if (oldPathStatus) {
        prev.set(oldPathStatus.path, {
          changeType: cur.change_type,
          status: oldPathStatus.status,
          newPath: newPathStatus ? newPathStatus.path : null,
        });
      }
      if (newPathStatus) {
        prev.set(newPathStatus.path, {
          changeType: cur.change_type,
          status: newPathStatus.status,
          oldPath: oldPathStatus ? oldPathStatus.path : null,
        });
      }
      return prev;
    }, new Map());
  }

  _computeFileStatus(fileStatusMap, path) {
    // empty for modified files and old-name files
    // Show `Renamed` for renamed file
    const status = fileStatusMap.get(path);
    if (status.oldPath) {
      return 'Renamed';
    }
    return;
  }

  _groupFilesByOwners(codeOwnerStatusMap) {
    // 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 allFiles = [...this._fetchedOwners.keys()];
    const ownersFilesMap = new Map();
    const failedToFetchFiles = new Set();
    for (let i = 0; i < allFiles.length; i++) {
      const fileInfo = {
        path: allFiles[i],
        status: this._computeFileStatus(codeOwnerStatusMap, allFiles[i]),
      };
      // for files failed to fetch, add them to the special group
      if (this._fetchedOwners.get(fileInfo.path).error) {
        failedToFetchFiles.add(fileInfo);
        continue;
      }

      // do not include files still in fetching
      if (!this._fetchedOwners.get(fileInfo.path).owners) {
        continue;
      }
      const owners = [...this._fetchedOwners.get(fileInfo.path).owners];
      const ownersKey = owners
          .map(owner => owner.account._account_id)
          .sort()
          .join(',');
      ownersFilesMap.set(
          ownersKey,
          ownersFilesMap.get(ownersKey) || {files: [], owners}
      );
      ownersFilesMap.get(ownersKey).files.push(fileInfo);
    }
    const groupedItems = [];
    for (const ownersKey of ownersFilesMap.keys()) {
      const groupName = this.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: this.getGroupName(failedFiles),
        files: failedFiles,
        error: new Error(
            'Failed to fetch code owner info. Try to refresh the page.'),
      });
    }

    return groupedItems;
  }

  getGroupName(files) {
    const fileName = files[0].path.split('/').pop();
    return {
      name: fileName,
      prefix: files.length > 1 ? `+ ${files.length - 1} more` : '',
    };
  }

  isOnLatestPatchset(patchsetId) {
    const latestRevision = this.change.revisions[this.change.current_revision];
    return `${latestRevision._number}` === `${patchsetId}`;
  }

  /**
   * Recursively fetches code owners for all files until finished.
   *
   * @param {!Array<string>} files
   */
  async _batchFetchCodeOwners(files) {
    if (this._fetchStatus === FetchStatus.ABORT) {
      return this._fetchedOwners;
    }

    const batchRequests = [];
    const maxConcurrentRequests = this.options.maxConcurrentRequests;
    for (let i = 0; i < maxConcurrentRequests; i++) {
      const filePath = files[i];
      if (filePath) {
        this._fetchedOwners.set(filePath, {});
        batchRequests.push(this._fetchOwnersForPath(this.change.id, filePath));
      }
    }
    const resPromise = Promise.all(batchRequests);
    await resPromise;
    if (files.length > maxConcurrentRequests) {
      return await this._batchFetchCodeOwners(
          files.slice(maxConcurrentRequests));
    }
    return this._fetchedOwners;
  }

  async _fetchOwnersForPath(changeId, filePath) {
    try {
      const owners = await this.codeOwnerCacheApi.listOwnersForPath(filePath);
      this._fetchedOwners.get(filePath).owners = new Set(owners);
    } catch (e) {
      this._fetchedOwners.get(filePath).error = e;
    }
  }

  abort() {
    this._fetchStatus = FetchStatus.ABORT;
    this._fetchedOwners = new Map();
    this._totalFetchCount = 0;
    const codeOwnerApi = new CodeOwnerApi(this.restApi);
    this.codeOwnerCacheApi = new CodeOwnersCacheApi(codeOwnerApi, change);
  }

  getBranchConfig() {
    return this.codeOwnerCacheApi.getBranchConfig();
  }

  async isCodeOwnerEnabled() {
    if (this.change.status === ChangeStatus.ABANDONED ||
        this.change.status === ChangeStatus.MERGED) {
      return false;
    }
    const config = await this.codeOwnerCacheApi.getBranchConfig();
    return !(config.status && config.status.disabled);
  }

  static getOwnerService(restApi, change) {
    if (!this.ownerService || this.ownerService.change !== change) {
      this.ownerService = new CodeOwnerService(restApi, change, {
        // Chrome has a limit of 6 connections per host name, and a max of 10 connections.
        maxConcurrentRequests: 6,
      });
      this.ownerService.prefetch();
    }
    return this.ownerService;
  }
}
