// 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.GrGapiAuth) { return; }

  const EMAIL_SCOPE = 'email';

  function GrGapiAuth() {}

  GrGapiAuth._loadGapiPromise = null;
  GrGapiAuth._setupPromise = null;
  GrGapiAuth._refreshTokenPromise = null;
  GrGapiAuth._sharedAuthToken = null;
  GrGapiAuth._oauthClientId = null;
  GrGapiAuth._oauthEmail = null;

  GrGapiAuth.prototype.fetch = function(url, options) {
    options = Object.assign({}, options);
    return this._getAccessToken().then(
        token => window.FASTER_GERRIT_CORS ?
            this._fasterGerritCors(url, options, token) :
            this._defaultFetch(url, options, token)
    );
  };

  GrGapiAuth.prototype._defaultFetch = function(url, options, token) {
    if (token) {
      options.headers = options.headers || new Headers();
      options.headers.append('Authorization', `Bearer ${token}`);
      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);
      }
    }
    return fetch(url, options);
  };

  GrGapiAuth.prototype._fasterGerritCors = function(url, options, token) {
    const method = options.method || 'GET';
    if (method === 'GET') {
      return fetch(url, options);
    }
    const params = [];
    if (token) {
      params.push(`access_token=${token}`);
    }
    const contentType = options.headers && options.headers.get('Content-Type');
    if (contentType) {
      options.headers.set('Content-Type', 'text/plain');
      params.push(`$ct=${encodeURIComponent(contentType)}`);
    }
    params.push(`$m=${method}`);
    url = url + (url.indexOf('?') === -1 ? '?' : '') + params.join('&');
    options.method = 'POST';
    return fetch(url, options);
  };

  GrGapiAuth.prototype._getAccessToken = function() {
    if (this._isTokenValid(GrGapiAuth._sharedAuthToken)) {
      return Promise.resolve(GrGapiAuth._sharedAuthToken.access_token);
    }
    if (!GrGapiAuth._refreshTokenPromise) {
      GrGapiAuth._refreshTokenPromise = this._loadGapi()
        .then(() => this._configureOAuthLibrary())
        .then(() => this._refreshToken())
        .then(token => {
          GrGapiAuth._sharedAuthToken = token;
          GrGapiAuth._refreshTokenPromise = null;
          return this._getAccessToken();
        }).catch(err => {
          console.error(err);
        });
    }
    return GrGapiAuth._refreshTokenPromise;
  };

  GrGapiAuth.prototype._isTokenValid = function(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;
  };

  GrGapiAuth.prototype._loadGapi = function() {
    if (!GrGapiAuth._loadGapiPromise) {
      GrGapiAuth._loadGapiPromise = new Promise((resolve, reject) => {
        const scriptEl = document.createElement('script');
        scriptEl.defer = true;
        scriptEl.async = true;
        scriptEl.src = 'https://apis.google.com/js/platform.js';
        scriptEl.onerror = reject;
        scriptEl.onload = resolve;
        document.body.appendChild(scriptEl);
      });
    }
    return GrGapiAuth._loadGapiPromise;
  };

  GrGapiAuth.prototype._configureOAuthLibrary = function() {
    if (!GrGapiAuth._setupPromise) {
      GrGapiAuth._setupPromise = new Promise(
        resolve => gapi.load('config_min', resolve)
      )
        .then(() => this._getOAuthConfig())
        .then(config => {
          if (config.hasOwnProperty('auth_url') && config.auth_url) {
            gapi.config.update('oauth-flow/authUrl', config.auth_url);
          }
          if (config.hasOwnProperty('proxy_url') && config.proxy_url) {
            gapi.config.update('oauth-flow/proxyUrl', config.proxy_url);
          }
          GrGapiAuth._oauthClientId = config.client_id;
          GrGapiAuth._oauthEmail = config.email;

          // Loading auth has a side-effect. The URLs should be set before
          // loading it.
          return new Promise(
            resolve => gapi.load('auth', () => gapi.auth.init(resolve))
          );
        });
    }
    return GrGapiAuth._setupPromise;
  };

  GrGapiAuth.prototype._refreshToken = function() {
    const opts = {
      client_id: GrGapiAuth._oauthClientId,
      immediate: true,
      scope: EMAIL_SCOPE,
      login_hint: GrGapiAuth._oauthEmail,
    };
    return new Promise((resolve, reject) => {
      gapi.auth.authorize(opts, token => {
        if (!token) {
          reject('No token returned');
        } else if (token.error) {
          reject(token.error);
        } else {
          resolve(token);
        }
      });
    });
  };

  GrGapiAuth.prototype._getOAuthConfig = function() {
    const baseUrl = Gerrit.BaseUrlBehavior.getBaseUrl();
    const authConfigURL = baseUrl + '/accounts/self/oauthconfig';
    const opts = {
      headers: new Headers({Accept: 'application/json'}),
      credentials: 'same-origin',
    };
    return fetch(authConfigURL, opts).then(response => {
      if (!response.ok) {
        console.error(response.statusText);
        if (response.body && response.body.then) {
          return response.body.then(text => {
            return Promise.reject(text);
          });
        }
        if (response.statusText) {
          return Promise.reject(response.statusText);
        } else {
          return Promise.reject('_getOAuthConfig' + response.status);
        }
      }
      return this._getResponseObject(response);
    });
  };

  GrGapiAuth.prototype._getResponseObject = function(response) {
    const JSON_PREFIX = ')]}\'';
    return response.text().then(text => {
      return JSON.parse(text.substring(JSON_PREFIX.length));
    });
  },

  window.GrGapiAuth = GrGapiAuth;
})(window);
