/**
 * @license
 * Copyright (C) 2017 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 {HttpMethod} from '../../../constants/constants';
import {RequestPayload} from '../../../types/common';
import {appContext} from '../../../services/app-context';
import {ErrorCallback, RestPluginApi} from '../../../api/rest';
import {PluginApi} from '../../../api/plugin';

async function getErrorMessage(response: Response): Promise<string> {
  const text = await response.text();
  return text || `${response.status}`;
}

// This is an internal error, that must never be visible outside of this
// file. It is used only inside GrPluginRestApi.send method. See detailed
// explanation in the GrPluginRestApi.send method.
class ResponseError extends Error {
  public constructor(readonly response: Response) {
    super();
  }
}

export class GrPluginRestApi implements RestPluginApi {
  private readonly restApi = appContext.restApiService;

  private readonly reporting = appContext.reportingService;

  constructor(readonly plugin: PluginApi, private readonly prefix = '') {
    this.reporting.trackApi(this.plugin, 'rest', 'constructor');
  }

  getLoggedIn() {
    this.reporting.trackApi(this.plugin, 'rest', 'getLoggedIn');
    return this.restApi.getLoggedIn();
  }

  getVersion() {
    this.reporting.trackApi(this.plugin, 'rest', 'getVersion');
    return this.restApi.getVersion();
  }

  getConfig() {
    this.reporting.trackApi(this.plugin, 'rest', 'getConfig');
    return this.restApi.getConfig();
  }

  invalidateReposCache() {
    this.reporting.trackApi(this.plugin, 'rest', 'invalidateReposCache');
    this.restApi.invalidateReposCache();
  }

  getAccount() {
    this.reporting.trackApi(this.plugin, 'rest', 'getAccount');
    return this.restApi.getAccount();
  }

  getAccountCapabilities(capabilities: string[]) {
    this.reporting.trackApi(this.plugin, 'rest', 'getAccountCapabilities');
    return this.restApi.getAccountCapabilities(capabilities);
  }

  getRepos(filter: string, reposPerPage: number, offset?: number) {
    this.reporting.trackApi(this.plugin, 'rest', 'getRepos');
    return this.restApi.getRepos(filter, reposPerPage, offset);
  }

  fetch(
    method: HttpMethod,
    url: string,
    payload?: RequestPayload,
    errFn?: undefined,
    contentType?: string
  ): Promise<Response>;

  fetch(
    method: HttpMethod,
    url: string,
    payload: RequestPayload | undefined,
    errFn: ErrorCallback,
    contentType?: string
  ): Promise<Response | void>;

  fetch(
    method: HttpMethod,
    url: string,
    payload: RequestPayload | undefined,
    errFn?: ErrorCallback,
    contentType?: string
  ): Promise<Response | void>;

  /**
   * Fetch and return native browser REST API Response.
   */
  fetch(
    method: HttpMethod,
    url: string,
    payload?: RequestPayload,
    errFn?: ErrorCallback,
    contentType?: string
  ): Promise<Response | void> {
    this.reporting.trackApi(this.plugin, 'rest', 'fetch');
    return this.restApi.send(
      method,
      this.prefix + url,
      payload,
      errFn,
      contentType
    );
  }

  /**
   * Fetch and parse REST API response, if request succeeds.
   */
  send<T>(
    method: HttpMethod,
    url: string,
    payload?: RequestPayload,
    errFn?: ErrorCallback,
    contentType?: string
  ) {
    this.reporting.trackApi(this.plugin, 'rest', 'send');
    // Plugins typically don't want Gerrit to show error dialogs for failed
    // requests. So we are defining a default errFn here, even if it is not
    // explicitly set by the caller.
    // TODO: We are soon getting rid of the `errFn` altogether. There are only
    // 2 known usages of errFn in plugins: delete-project and verify-status.
    errFn =
      errFn ??
      ((response: Response | null | undefined, error?: Error) => {
        if (error) throw error;
        // Some plugins show an error message if send is failed, smth like:
        // pluginApi.send(...).catch(err => showError(err));
        // The response can contain an error text, but getting this text is
        // an asynchronous operation. At the same time, the errFn must be a
        // synchronous function.
        // As a workaround, we throw an ResponseError here and then catch
        // it inside a catch block below and read the message.
        if (response) throw new ResponseError(response);
        throw new Error('Generic REST API error.');
      });
    return this.fetch(method, url, payload, errFn, contentType)
      .then(response => {
        // Will typically not happen. The response can only be unset, if the
        // errFn handles the error and then returns void or undefined or null.
        // But the errFn above always throws.
        if (!response) {
          throw new Error('plugin rest-api call failed');
        }
        // Will typically not happen. errFn will have dealt with that and the
        // caller will get a rejected promise already.
        if (response.status < 200 || response.status >= 300) {
          return getErrorMessage(response).then(msg =>
            Promise.reject(new Error(msg))
          );
        } else {
          return this.restApi.getResponseObject(response) as Promise<T>;
        }
      })
      .catch(err => {
        if (err instanceof ResponseError) {
          return getErrorMessage(err.response).then(msg => {
            throw new Error(msg);
          });
        }
        throw err;
      });
  }

  get<T>(url: string) {
    this.reporting.trackApi(this.plugin, 'rest', 'get');
    return this.send<T>(HttpMethod.GET, url);
  }

  post<T>(
    url: string,
    payload?: RequestPayload,
    errFn?: ErrorCallback,
    contentType?: string
  ) {
    this.reporting.trackApi(this.plugin, 'rest', 'post');
    return this.send<T>(HttpMethod.POST, url, payload, errFn, contentType);
  }

  put<T>(
    url: string,
    payload?: RequestPayload,
    errFn?: ErrorCallback,
    contentType?: string
  ) {
    this.reporting.trackApi(this.plugin, 'rest', 'put');
    return this.send<T>(HttpMethod.PUT, url, payload, errFn, contentType);
  }

  delete(url: string) {
    this.reporting.trackApi(this.plugin, 'rest', 'delete');
    return this.fetch(HttpMethod.DELETE, url).then(response => {
      if (response.status !== 204) {
        return response.text().then(text => {
          if (text) {
            return Promise.reject(new Error(text));
          } else {
            return Promise.reject(new Error(`${response.status}`));
          }
        });
      }
      return response;
    });
  }
}
