{{#useAxiosHttpModule}}
import { DynamicModule, Module, Global, Provider } from '@nestjs/common';
import { HttpModule, HttpService } from '@nestjs/axios';
{{/useAxiosHttpModule}}
{{^useAxiosHttpModule}}
import { DynamicModule, HttpService, HttpModule, Module, Global, Provider } from '@nestjs/common';
{{/useAxiosHttpModule}}
import { AsyncConfiguration, Configuration, ConfigurationFactory } from './configuration';

{{#apiInfo}}
{{#apis}}
import { {{classname}} } from './{{importPath}}';
{{/apis}}
{{/apiInfo}}

@Global()
@Module({
  imports:      [ HttpModule ],
  exports:      [
    {{#apiInfo}}{{#apis}}{{classname}}{{^-last}},
    {{/-last}}{{/apis}}{{/apiInfo}}
  ],
  providers: [
    {{#apiInfo}}{{#apis}}{{classname}}{{^-last}},
    {{/-last}}{{/apis}}{{/apiInfo}}
  ]
})
export class ApiModule {
    public static forRoot(configurationFactory: () => Configuration): DynamicModule {
        return {
            module: ApiModule,
            providers: [ { provide: Configuration, useFactory: configurationFactory } ]
        };
    }

    /**
     * Register the module asynchronously.
     */
    static forRootAsync(options: AsyncConfiguration): DynamicModule {
        const providers = [...this.createAsyncProviders(options)];
        return {
            module: ApiModule,
            imports: options.imports || [],
            providers,
            exports: providers,
        };
    }

    private static createAsyncProviders(options: AsyncConfiguration): Provider[] {
        if (options.useClass) {
            return [
                this.createAsyncConfigurationProvider(options),
                {
                    provide: options.useClass,
                    useClass: options.useClass,
                },
            ];
        }
        return [this.createAsyncConfigurationProvider(options)];
    }

    private static createAsyncConfigurationProvider(
        options: AsyncConfiguration,
    ): Provider {
        if (options.useFactory) {
            return {
                provide: Configuration,
                useFactory: options.useFactory,
                inject: options.inject || [],
            };
        }
        return {
            provide: Configuration,
            useFactory: async (optionsFactory: ConfigurationFactory) =>
                await optionsFactory.createConfiguration(),
            inject: (options.useExisting && [options.useExisting]) || (options.useClass && [options.useClass]) || [],
        };
    }

    constructor( httpService: HttpService) { }
}
