// angular modules
import { NgModule, APP_INITIALIZER, ModuleWithProviders, Injector, Optional, SkipSelf } from '@angular/core';
import { DatePipe } from '@angular/common';
import { HTTP_INTERCEPTORS } from '@angular/common/http';

// external modules
import { OAuthModule, OAuthService, OAuthStorage } from 'angular-oauth2-oidc';


//components
import { ItemTypeService } from './services/itemtype.service';
import { SchemaService } from './services/schema.service';
import { FolderService } from './services/folder.service';
import { TimespanService } from './services/timespan.service';
import { ItemService } from './services/item.service';
import { TaskService } from './services/task.service';
import { AdminService } from './services/admin.service';
import { EventService } from './services/event.service';
import { TypeaheadService } from './services/typeahead.service';
import { UserService } from './services/user.service';
import { ImageService } from './services/image.service';
import { DownloadService } from './services/download.service';
import { GeolocatorService } from './services/geolocator.service';
import { WeatherService} from './services/weather.service';
import { AppConfig } from './shared/app.config';
import { AccessTokenInterceptor } from "./shared/accesstoken.interceptor";
import { appConfigFactory } from "./shared/app.config.factory";
import { AuthGuard } from './services/auth-guard.service';
import { NavBarGuard } from './services/nav-bar-guard.service';
import { PackageGuard } from './services/package-guard.service';
import { FullScreenGuard } from './services/full-screen-guard.service';
import { AuthCallbackGuard } from './components/auth-callback/auth-callback.guard';
import { ResumableFileUploadService } from './components/resumable-file-upload/resumable-file-upload.service';
import { NgbDateNativeAdapter } from './services/date-adapter.service'
import { AuthConfigFactory } from './shared/authconfigFactory';
import { StateSerializerService } from './services/state-serializer.service';
import { PackageService } from './services/package.service';
import { PackagePreloadStrategy } from './services/package-preload-strategy.service';
import { SenmlService } from './services/senml-service';
import { DeviceService } from './services/device.service';
import { GradientService} from './services/gradient.service';

export {
  FolderService,
  ItemTypeService,
  TimespanService,
  ItemService,
  TaskService,
  AdminService,
  EventService,
  TypeaheadService,
  UserService,
  ImageService,
  DownloadService,
  GeolocatorService,
  WeatherService,
  AppConfig,
  AccessTokenInterceptor,
  AuthGuard,
  NavBarGuard,
  PackageGuard,
  FullScreenGuard,
  AuthCallbackGuard,
  ResumableFileUploadService,
  NgbDateNativeAdapter,
  StateSerializerService,
  SchemaService,
  PackageService,
  SenmlService,
  PackagePreloadStrategy,
  DeviceService,
  GradientService
};

@NgModule({
  imports: [
    OAuthModule.forRoot(),
  ]
})
export class AppCommonServiceModule {
  constructor(@Optional() @SkipSelf() parentModule: AppCommonServiceModule) {
    if (parentModule) {
      throw new Error(
        'AppCommonServiceModule is already loaded. Import it in the AppModule only');
    }
  }
  static forRoot(): ModuleWithProviders<AppCommonServiceModule> {
    return {
      ngModule: AppCommonServiceModule,
      providers: [
        AppConfig,
        ItemTypeService,
        {
          provide: APP_INITIALIZER,
          useFactory: appConfigFactory,
          deps: [Injector, AppConfig, OAuthService, AuthConfigFactory, OAuthStorage, ItemTypeService],
          multi: true
        },
        {
          provide: HTTP_INTERCEPTORS,
          useClass: AccessTokenInterceptor,
          multi: true
        },
        DatePipe
      ]
    };
  }
}
