/**
 * @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.
 */
(function(window) {
  'use strict';

  // Prevent redefinition.
  if (window.Gerrit.Auth) { return; }

  const MAX_GET_TOKEN_RETRIES = 2;

  Gerrit.Auth = {
    TYPE: {
      XSRF_TOKEN: 'xsrf_token',
      ACCESS_TOKEN: 'access_token',
    },

    _type: null,
    _cachedTokenPromise: null,
    _defaultOptions: {},
    _retriesLeft: MAX_GET_TOKEN_RETRIES,

    _getToken() {
      return Promise.resolve(this._cachedTokenPromise);
    },

    /**
     * Enable cross-domain authentication using OAuth access token.
     *
     * @param {
     *   function(): !Promise<{
     *     access_token: string,
     *     expires_at: number
     *   }>
     * } getToken
     * @param {?{credentials:string}} defaultOptions
     */
    setup(getToken, defaultOptions) {
      this._retriesLeft = MAX_GET_TOKEN_RETRIES;
      if (getToken) {
        this._type = Gerrit.Auth.TYPE.ACCESS_TOKEN;
        this._cachedTokenPromise = null;
        this._getToken = getToken;
      }
      this._defaultOptions = {};
      if (defaultOptions) {
        for (const p of ['credentials']) {
          this._defaultOptions[p] = defaultOptions[p];
        }
      }
    },

    /**
     * Perform network fetch with authentication.
     *
     * @param {string} url
     * @param {Object=} opt_options
     * @return {!Promise<!Response>}
     */
    fetch(url, opt_options) {
      const options = Object.assign({
        headers: new Headers(),
      }, this._defaultOptions, opt_options);
      if (this._type === Gerrit.Auth.TYPE.ACCESS_TOKEN) {
        return this._getAccessToken().then(
            accessToken => this._fetchWithAccessToken(url, options, accessToken)
        );
      } else {
        return this._fetchWithXsrfToken(url, options);
      }
    },

    _getCookie(name) {
      const key = name + '=';
      let result = '';
      document.cookie.split(';').some(c => {
        c = c.trim();
        if (c.startsWith(key)) {
          result = c.substring(key.length);
          return true;
        }
      });
      return result;
    },

    _isTokenValid(token) {
      if (!token) { return false; }
      if (!token.access_token || !token.expires_at) { return false; }

      const expiration = new Date(parseInt(token.expires_at, 10) * 1000);
      if (Date.now() >= expiration.getTime()) { return false; }

      return true;
    },

    _fetchWithXsrfToken(url, options) {
      if (options.method && options.method !== 'GET') {
        const token = this._getCookie('XSRF_TOKEN');
        if (token) {
          options.headers.append('X-Gerrit-Auth', token);
        }
      }
      options.credentials = 'same-origin';
      return fetch(url, options);
    },

    /**
     * @return {!Promise<string>}
     */
    _getAccessToken() {
      if (!this._cachedTokenPromise) {
        this._cachedTokenPromise = this._getToken();
      }
      return this._cachedTokenPromise.then(token => {
        if (this._isTokenValid(token)) {
          this._retriesLeft = MAX_GET_TOKEN_RETRIES;
          return token.access_token;
        }
        if (this._retriesLeft > 0) {
          this._retriesLeft--;
          this._cachedTokenPromise = null;
          return this._getAccessToken();
        }
        // Fall back to anonymous access.
        return null;
      });
    },

    _fetchWithAccessToken(url, options, accessToken) {
      const params = [];

      if (accessToken) {
        params.push(`access_token=${accessToken}`);
        const baseUrl = Gerrit.BaseUrlBehavior.getBaseUrl();
        const pathname = baseUrl ?
          url.substring(url.indexOf(baseUrl) + baseUrl.length) : url;
        if (!pathname.startsWith('/a/')) {
          url = url.replace(pathname, '/a' + pathname);
        }
      }

      const method = options.method || 'GET';
      let contentType = options.headers.get('Content-Type');

      // For all requests with body, ensure json content type.
      if (!contentType && options.body) {
        contentType = 'application/json';
      }

      if (method !== 'GET') {
        options.method = 'POST';
        params.push(`$m=${method}`);
        // If a request is not GET, and does not have a body, ensure text/plain
        // content type.
        if (!contentType) {
          contentType = 'text/plain';
        }
      }

      if (contentType) {
        options.headers.set('Content-Type', 'text/plain');
        params.push(`$ct=${encodeURIComponent(contentType)}`);
      }

      if (params.length) {
        url = url + (url.indexOf('?') === -1 ? '?' : '&') + params.join('&');
      }
      return fetch(url, options);
    },
  };

  window.Gerrit.Auth = Gerrit.Auth;
})(window);
