/**
 * @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 {getAppContext} 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 = getAppContext().restApiService;

  private readonly reporting = getAppContext().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();
  }

  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;
    });
  }
}
