/** @chatkitty:generated **/
import globalAxios, {AxiosRequestConfig} from 'axios';
import tokenInterceptor = require('axios-token-interceptor');
import FormData = require('form-data');
import {
    AnalyticsApi,
    ApplicationApi,
    ChannelsApi,
    ChatSessionsApi,
    FunctionVersionsApi,
    FunctionsApi,
    ImportsApi,
    JobsApi,
    MessagesApi,
    RuntimeApi,
    ThreadsApi,
    UserSessionsApi,
    UsersApi
} from './api';
import { Configuration } from './configuration';

export interface ChatKittyConfiguration {
  /**
  * parameter for OAuth authorization client ID
  *
  * @type {string}
  * @memberof ChatKittyConfiguration
  */
  clientId: string;

  /**
  * parameter for OAuth authorization client secret
  *
  * @type {string}
  * @memberof ChatKittyConfiguration
  */
  clientSecret: string;

  /**
  * override base path
  *
  * @type {string}
  * @memberof ChatKittyConfiguration
  */
  basePath?: string;

  /**
  * override authorization base path
  *
  * @type {string}
  * @memberof ChatKittyConfiguration
  */
  authorizationBasePath?: string;
}

export class ChatKitty {
  constructor(private configuration: ChatKittyConfiguration) {
  }

  private _chatkitty_authorizingAxios = globalAxios.create();

  private _chatkitty_getClientCredentialsAccessToken = async () => {
    const data = new FormData();

    data.append('grant_type', 'client_credentials');

    let headers = {}

    if (data.getHeaders && data.getLengthSync) {
      headers = {
        ...data.getHeaders(),
        'Content-Length': data.getLengthSync()
      }
    }

    const configuration: AxiosRequestConfig = {
      url: this.configuration.authorizationBasePath ||
          'https://authorization.chatkitty.com/oauth/token',
      method: 'post',
      auth: {
        username: this.configuration.clientId,
        password: this.configuration.clientSecret,
      },
      headers,
      data,
    };

    return this._chatkitty_authorizingAxios(configuration).then(res => res.data);
  };

  private _chatkitty_token_cache = tokenInterceptor.tokenCache(
      this._chatkitty_getClientCredentialsAccessToken,
      {getMaxAge: (token: any) => token.expires_in * 1000},
  );

  private apiConfiguration: Configuration = new Configuration(
      {
        basePath: this.configuration.basePath,
        accessToken: async () => {
          const token: any = await this._chatkitty_token_cache();

          return token.access_token;
        },
        baseOptions: {
          headers: {
            'Accept': 'application/vnd.chatkitty+json,*/*;q=0.8',
          },
        },
        ...this.configuration,
      }
  );

      /** Instance of AnalyticsApi */
      public readonly AnalyticsApi: AnalyticsApi = new AnalyticsApi(this.apiConfiguration);
      /** Instance of ApplicationApi */
      public readonly ApplicationApi: ApplicationApi = new ApplicationApi(this.apiConfiguration);
      /** Instance of ChannelsApi */
      public readonly ChannelsApi: ChannelsApi = new ChannelsApi(this.apiConfiguration);
      /** Instance of ChatSessionsApi */
      public readonly ChatSessionsApi: ChatSessionsApi = new ChatSessionsApi(this.apiConfiguration);
      /** Instance of FunctionVersionsApi */
      public readonly FunctionVersionsApi: FunctionVersionsApi = new FunctionVersionsApi(this.apiConfiguration);
      /** Instance of FunctionsApi */
      public readonly FunctionsApi: FunctionsApi = new FunctionsApi(this.apiConfiguration);
      /** Instance of ImportsApi */
      public readonly ImportsApi: ImportsApi = new ImportsApi(this.apiConfiguration);
      /** Instance of JobsApi */
      public readonly JobsApi: JobsApi = new JobsApi(this.apiConfiguration);
      /** Instance of MessagesApi */
      public readonly MessagesApi: MessagesApi = new MessagesApi(this.apiConfiguration);
      /** Instance of RuntimeApi */
      public readonly RuntimeApi: RuntimeApi = new RuntimeApi(this.apiConfiguration);
      /** Instance of ThreadsApi */
      public readonly ThreadsApi: ThreadsApi = new ThreadsApi(this.apiConfiguration);
      /** Instance of UserSessionsApi */
      public readonly UserSessionsApi: UserSessionsApi = new UserSessionsApi(this.apiConfiguration);
      /** Instance of UsersApi */
      public readonly UsersApi: UsersApi = new UsersApi(this.apiConfiguration);
}
