/**
 * @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_AUTH_CHECK_WAIT_TIME_MS = 1000 * 30; // 30s
  const MAX_GET_TOKEN_RETRIES = 2;

  /**
   * Auth class.
   *
   * Gerrit.Auth is an instance of this class.
   */
  class Auth {
    constructor() {
      this._type = null;
      this._cachedTokenPromise = null;
      this._defaultOptions = {};
      this._retriesLeft = MAX_GET_TOKEN_RETRIES;
      this._status = Auth.STATUS.UNDETERMINED;
      this._authCheckPromise = null;
      this._last_auth_check_time = Date.now();
    }

    /**
     * Returns if user is authed or not.
     *
     * @returns {!Promise<boolean>}
     */
    authCheck() {
      if (!this._authCheckPromise ||
        (Date.now() - this._last_auth_check_time > MAX_AUTH_CHECK_WAIT_TIME_MS)
      ) {
        // Refetch after last check expired
        this._authCheckPromise = fetch('/auth-check');
        this._last_auth_check_time = Date.now();
      }

      return this._authCheckPromise.then(res => {
        // auth-check will return 204 if authed
        // treat the rest as unauthed
        if (res.status === 204) {
          this._setStatus(Auth.STATUS.AUTHED);
          return true;
        } else {
          this._setStatus(Auth.STATUS.NOT_AUTHED);
          return false;
        }
      }).catch(e => {
        this._setStatus(Auth.STATUS.ERROR);
        // Reset _authCheckPromise to avoid caching the failed promise
        this._authCheckPromise = null;
        return false;
      });
    }

    clearCache() {
      this._authCheckPromise = null;
    }

    /**
     * @param {string} status
     */
    _setStatus(status) {
      if (this._status === status) return;

      if (this._status === Auth.STATUS.AUTHED) {
        Gerrit.emit('auth-error', {
          message: Auth.CREDS_EXPIRED_MSG, action: 'Refresh credentials',
        });
      }
      this._status = status;
    }

    get status() {
      return this._status;
    }

    get isAuthed() {
      return this._status === Auth.STATUS.AUTHED;
    }

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

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

  Auth.STATUS = {
    UNDETERMINED: 0,
    AUTHED: 1,
    NOT_AUTHED: 2,
    ERROR: 3,
  };

  Auth.CREDS_EXPIRED_MSG = 'Credentails expired.';

  // TODO(taoalpha): this whole thing should be moved to a service
  window.Auth = Auth;
  Gerrit.Auth = new Auth();
})(window);
