/**
 * Shell Card Management APIsLib
 *
 * This file was automatically generated by APIMATIC v3.0 ( https://www.apimatic.io ).
 */

import {
  compositeAuthenticationProvider,
  OAuthConfiguration,
  requestAuthenticationProvider,
} from './authentication.js';
import { ClientCredentialsAuthManager } from './clientCredentialsAuthManager.js';
import { Configuration } from './configuration.js';
import { OAuthToken } from './models/oAuthToken.js';

export function createAuthProviderFromConfig(
  config: Partial<Configuration>,
  bearerToken: () => ClientCredentialsAuthManager
) {
  const authConfig = {
    bearerToken:
      config.clientCredentialsAuthCredentials &&
      requestAuthenticationProvider(
        config.clientCredentialsAuthCredentials.oAuthToken,
        bearerTokenTokenProvider(
          bearerToken,
          config.clientCredentialsAuthCredentials.oAuthTokenProvider
        ),
        config.clientCredentialsAuthCredentials.oAuthOnTokenUpdate,
        {
          clockSkew: config.clientCredentialsAuthCredentials.oAuthClockSkew,
        } as OAuthConfiguration
      ),
  };

  return compositeAuthenticationProvider<
    keyof typeof authConfig,
    typeof authConfig
  >(authConfig);
}

function bearerTokenTokenProvider(
  bearerToken: () => ClientCredentialsAuthManager,
  defaultProvider:
    | ((
        lastOAuthToken: OAuthToken | undefined,
        authManager: ClientCredentialsAuthManager
      ) => Promise<OAuthToken>)
    | undefined
): ((token: OAuthToken | undefined) => Promise<OAuthToken>) | undefined {
  return (token: OAuthToken | undefined) => {
    const manager = bearerToken();
    if (defaultProvider === undefined) {
      return manager.updateToken(token);
    }
    return defaultProvider(token, manager);
  };
}
