/**
 * @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 {ChangeInfo} from '@gerritcodereview/typescript-api/rest-api.js';
import {RestPluginApi} from '@gerritcodereview/typescript-api/rest.js';
import {CodeOwnersApi, FetchedOwner, OwnerStatus} from './code-owners-api.js';
import {FileStatus} from './code-owners-model.js';

/**
 * @enum
 */
export const FetchStatus = {
  /** Fetch hasn't been started */
  NOT_STARTED: 0,
  /**
   * Fetch has been started, but not all files has been finished.
   * Pausing during fetching doesn't change state.
   */
  FETCHING: 1,
  /**
   * All owners has been loaded. resume/pause call doesn't change state.
   */
  FINISHED: 2,
};

/**
 * Fetch owners for files. The class fetches owners in parallel and allows to
 * pause/resume fetch.
 */
class OwnersFetcher {
  private paused = true;

  private fetchedOwners = new Map<string, FetchedOwner>();

  private pausedFilesFetcher: Array<() => void> = [];

  private fetchFilesPromises: Array<Promise<void>> = [];

  /**
   * Creates a fetcher in paused state. Actual fetching starts after resume()
   * is called.
   */
  constructor(
    private readonly codeOwnerApi: CodeOwnersApi,
    private readonly change: ChangeInfo,
    private readonly filesToFetch: Array<string>,
    private readonly ownersLimit: number,
    maxConcurrentRequest: number
  ) {
    for (let i = 0; i < maxConcurrentRequest; i++) {
      this.fetchFilesPromises.push(this.fetchFiles());
    }
  }

  private async fetchFiles() {
    for (;;) {
      const filePath = await this.getNextFilePath();
      if (!filePath) return;
      try {
        this.fetchedOwners.set(filePath, {
          owners: await this.codeOwnerApi.listOwnersForPath(
            this.change,
            filePath,
            this.ownersLimit
          ),
        });
      } catch (error) {
        this.fetchedOwners.set(filePath, {error});
      }
    }
  }

  private async getNextFilePath() {
    if (this.paused) {
      await new Promise<void>(resolve => this.pausedFilesFetcher.push(resolve));
    }
    if (this.filesToFetch.length === 0) return null;
    return this.filesToFetch.splice(0, 1)[0];
  }

  async waitFetchComplete() {
    // Simplified polyfill allSettled
    // TODO: Replace with allSettled once minimal node version is updated.
    await Promise.all(
      this.fetchFilesPromises.map(p =>
        p.then(() => 'succeeded').catch(_reason => 'rejected')
      )
    );
  }

  resume() {
    if (!this.paused) return;
    this.paused = false;
    for (const fetcher of this.pausedFilesFetcher.splice(
      0,
      this.pausedFilesFetcher.length
    )) {
      fetcher();
    }
  }

  pause() {
    this.paused = true;
  }

  getFetchedOwners() {
    return this.fetchedOwners;
  }

  getFiles(): Array<{path: string; info: FetchedOwner}> {
    const result = [];
    for (const [path, info] of this.fetchedOwners.entries()) {
      result.push({path, info});
    }
    return result;
  }
}

export class OwnersProvider {
  private status = FetchStatus.NOT_STARTED;

  private totalFetchCount = 0;

  private codeOwnerApi: CodeOwnersApi;

  private ownersFetcher?: OwnersFetcher;

  constructor(
    restApi: RestPluginApi,
    private readonly change: ChangeInfo,
    private readonly options: {
      maxConcurrentRequests: number;
      ownersLimit: number;
    }
  ) {
    this.codeOwnerApi = new CodeOwnersApi(restApi);
  }

  getStatus() {
    return this.status;
  }

  getProgressString() {
    return !this.ownersFetcher || this.totalFetchCount === 0
      ? 'Loading suggested owners ...'
      : `${this.ownersFetcher.getFetchedOwners().size} out of ` +
          `${this.totalFetchCount} files have returned suggested owners.`;
  }

  getFiles() {
    if (!this.ownersFetcher) return [];
    return this.ownersFetcher.getFiles();
  }

  async fetchSuggestedOwners(codeOwnerStatusMap: Map<string, FileStatus>) {
    if (this.status !== FetchStatus.NOT_STARTED) {
      await this.ownersFetcher!.waitFetchComplete();
      return;
    }
    const filesToFetch = this._getFilesToFetch(codeOwnerStatusMap);
    this.totalFetchCount = filesToFetch.length;
    this.ownersFetcher = new OwnersFetcher(
      this.codeOwnerApi,
      this.change,
      filesToFetch,
      this.options.ownersLimit,
      this.options.maxConcurrentRequests
    );
    this.status = FetchStatus.FETCHING;
    this.ownersFetcher.resume();
    await this.ownersFetcher.waitFetchComplete();
    this.status = FetchStatus.FINISHED;
  }

  _getFilesToFetch(codeOwnerStatusMap: Map<string, FileStatus>) {
    // only fetch those not approved yet
    const filesGroupByStatus = [...codeOwnerStatusMap.entries()].reduce(
      (list, [file, fileInfo]) => {
        if (list[fileInfo.status]) list[fileInfo.status].push(file);
        return list;
      },
      {
        [OwnerStatus.PENDING]: [] as Array<string>,
        [OwnerStatus.INSUFFICIENT_REVIEWERS]: [] as Array<string>,
        [OwnerStatus.APPROVED]: [] as Array<string>,
      }
    );
    // always fetch INSUFFICIENT_REVIEWERS first, then pending and then approved
    return filesGroupByStatus[OwnerStatus.INSUFFICIENT_REVIEWERS]
      .concat(filesGroupByStatus[OwnerStatus.PENDING])
      .concat(filesGroupByStatus[OwnerStatus.APPROVED]);
  }

  pause() {
    if (!this.ownersFetcher) return;
    this.ownersFetcher.pause();
  }

  resume() {
    if (!this.ownersFetcher) return;
    this.ownersFetcher.resume();
  }

  reset() {
    this.totalFetchCount = 0;
    this.ownersFetcher = undefined;
    this.status = FetchStatus.NOT_STARTED;
  }
}
