/**
 * @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);
