/**
 * @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 {getBaseUrl} from '../../utils/url-util';
import {EventEmitterService} from '../gr-event-interface/gr-event-interface';
import {Finalizable} from '../registry';
import {
  AuthRequestInit,
  AuthService,
  AuthStatus,
  AuthType,
  DefaultAuthOptions,
  GetTokenCallback,
  Token,
} from './gr-auth';

export const MAX_AUTH_CHECK_WAIT_TIME_MS = 1000 * 30; // 30s
const MAX_GET_TOKEN_RETRIES = 2;

interface ValidToken extends Token {
  access_token: string;
  expires_at: string;
}

interface AuthRequestInitWithHeaders extends AuthRequestInit {
  // RequestInit define headers as optional property with a type
  // Headers | string[][] | Record<string, string>
  // In Auth class headers property is always set and has type Headers
  headers: Headers;
}

/**
 * Auth class.
 */
export class Auth implements AuthService, Finalizable {
  // TODO(dmfilippov): Remove Type and Status properties, expose AuthType and
  // AuthStatus to API
  static TYPE = {
    XSRF_TOKEN: AuthType.XSRF_TOKEN,
    ACCESS_TOKEN: AuthType.ACCESS_TOKEN,
  };

  static STATUS = {
    UNDETERMINED: AuthStatus.UNDETERMINED,
    AUTHED: AuthStatus.AUTHED,
    NOT_AUTHED: AuthStatus.NOT_AUTHED,
    ERROR: AuthStatus.ERROR,
  };

  static CREDS_EXPIRED_MSG = 'Credentials expired.';

  private authCheckPromise?: Promise<Response>;

  private _last_auth_check_time: number = Date.now();

  private _status = AuthStatus.UNDETERMINED;

  private retriesLeft = MAX_GET_TOKEN_RETRIES;

  private cachedTokenPromise: Promise<Token | null> | null = null;

  private type?: AuthType;

  private defaultOptions: AuthRequestInit = {};

  private getToken: GetTokenCallback;

  public eventEmitter: EventEmitterService;

  constructor(eventEmitter: EventEmitterService) {
    this.getToken = () => Promise.resolve(this.cachedTokenPromise);
    this.eventEmitter = eventEmitter;
  }

  get baseUrl() {
    return getBaseUrl();
  }

  finalize() {}

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

    return this.authCheckPromise
      .then(res => {
        // Make a call that requires loading the body of the request. This makes it so that the browser
        // can close the request even though callers of this method might only ever read headers.
        // See https://stackoverflow.com/questions/45816743/how-to-solve-this-caution-request-is-not-finished-yet-in-chrome
        try {
          res.clone().text();
        } catch {
          // Ignore error
        }

        // 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(() => {
        this._setStatus(AuthStatus.ERROR);
        // Reset authCheckPromise to avoid caching the failed promise
        this.authCheckPromise = undefined;
        return false;
      });
  }

  clearCache() {
    this.authCheckPromise = undefined;
  }

  private _setStatus(status: AuthStatus) {
    if (this._status === status) return;

    if (this._status === AuthStatus.AUTHED) {
      this.eventEmitter.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;
  }

  /**
   * Enable cross-domain authentication using OAuth access token.
   */
  setup(getToken: GetTokenCallback, defaultOptions: DefaultAuthOptions) {
    this.retriesLeft = MAX_GET_TOKEN_RETRIES;
    if (getToken) {
      this.type = AuthType.ACCESS_TOKEN;
      this.cachedTokenPromise = null;
      this.getToken = getToken;
    }
    this.defaultOptions = {};
    if (defaultOptions) {
      this.defaultOptions.credentials = defaultOptions.credentials;
    }
  }

  /**
   * Perform network fetch with authentication.
   */
  fetch(url: string, opt_options?: AuthRequestInit): Promise<Response> {
    const options: AuthRequestInitWithHeaders = {
      headers: new Headers(),
      ...this.defaultOptions,
      ...opt_options,
    };
    if (this.type === AuthType.ACCESS_TOKEN) {
      return this._getAccessToken().then(accessToken =>
        this._fetchWithAccessToken(url, options, accessToken)
      );
    } else {
      return this._fetchWithXsrfToken(url, options);
    }
  }

  private _getCookie(name: string): string {
    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 false;
    });
    return result;
  }

  private _isTokenValid(token: Token | null): token is ValidToken {
    if (!token) {
      return false;
    }
    if (!token.access_token || !token.expires_at) {
      return false;
    }

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

    return true;
  }

  private _fetchWithXsrfToken(
    url: string,
    options: AuthRequestInitWithHeaders
  ): Promise<Response> {
    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 this._ensureBodyLoaded(fetch(url, options));
  }

  private _getAccessToken(): Promise<string | null> {
    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;
    });
  }

  private _fetchWithAccessToken(
    url: string,
    options: AuthRequestInitWithHeaders,
    accessToken: string | null
  ): Promise<Response> {
    const params = [];

    if (accessToken) {
      params.push(`access_token=${accessToken}`);
      const baseUrl = this.baseUrl;
      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 this._ensureBodyLoaded(fetch(url, options));
  }

  private _ensureBodyLoaded(response: Promise<Response>): Promise<Response> {
    return response.then(response => {
      if (!response.ok) {
        // Make a call that requires loading the body of the request. This makes it so that the browser
        // can close the request even though callers of this method might only ever read headers.
        // See https://stackoverflow.com/questions/45816743/how-to-solve-this-caution-request-is-not-finished-yet-in-chrome
        try {
          response.clone().text();
        } catch {
          // Ignore error
        }
      }
      return response;
    });
  }
}
