/**
 * @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.
 */

// TODO: Try to remove it. The ResponseError and getErrorMessage duplicates
// code from the gr-plugin-rest-api.ts. This code is required because
// we want custom error processing in some functions. For details see
// the original gr-plugin-rest-api.ts file/
class ResponseError extends Error {
  constructor(response) {
    super();
    this.response = response;
  }
}

export class ServerConfigurationError extends Error {
  constructor(msg) {
    super(msg);
  }
}

async function getErrorMessage(response) {
  const text = await response.text();
  return text ?
    `${response.status}: ${text}` :
    `${response.status}`;
}

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

  /**
   * Send a get request and provides custom response-code handling
   */
  async _get(url) {
    const errFn = (response, error) => {
      if (error) throw error;
      if (response) throw new ResponseError(response);
      throw new Error('Generic REST API error');
    };
    try {
      return await this.restApi.send(
          'GET',
          url,
          undefined,
          errFn
      );
    } catch (err) {
      if (err instanceof ResponseError && err.response.status === 409) {
        return getErrorMessage(err.response).then(msg => {
          throw new ServerConfigurationError(msg);
        });
      }
      throw err;
    }
  }

  /**
   * 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._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, limit) {
    return this._get(
        `/changes/${changeId}/revisions/current/code_owners` +
        `/${encodeURIComponent(path)}?limit=${limit}&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._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
   */
  async getBranchConfig(project, branch) {
    try {
      const config = await this._get(
          `/projects/${encodeURIComponent(project)}/` +
          `branches/${encodeURIComponent(branch)}/` +
          `code_owners.branch_config`
      );
      if (config.override_approval &&
          !(config.override_approval instanceof Array)) {
        // In the upcoming backend changes, the override_approval will be changed
        // to array with (possible) multiple items.
        // While this transition is in progress, the frontend supports both API -
        // the old one and the new one.
        return {...config, override_approval: [config.override_approval]};
      }
      return config;
    } catch (err) {
      if (err instanceof ResponseError) {
        if (err.response.status === 404) {
          // The 404 error means that the branch doesn't exist and
          // the plugin should be disabled.
          return {disabled: true};
        }
        return getErrorMessage(err.response).then(msg => {
          throw new Error(msg);
        });
      }
      throw err;
    }
  }
}

/**
 * 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 inconsistency, the cache doesn't invalidate.
 */
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));
  }
}
