import { Global, Module } from '@nestjs/common';
  import { ConfigService } from '@nestjs/config';
  import { DataSource } from 'typeorm';
  import { AppConfig } from '../config/configuration';
  import { createLandlordDataSource } from './landlord-data-source';
  import { TenantConnectionService } from './tenant-connection.service';

  export const LANDLORD_DATA_SOURCE = 'LANDLORD_DATA_SOURCE';
  export const TENANT_DATA_SOURCE = 'TENANT_DATA_SOURCE';

  function buildAppConfig(cs: ConfigService): AppConfig {
    return {
      port: cs.get<number>('port')!,
      nodeEnv: cs.get<string>('nodeEnv')!,
      jwt: {
        secret: cs.get<string>('jwt.secret')!,
        expiresIn: cs.get<string>('jwt.expiresIn')!,
      },
      db: {
        driver: cs.get<AppConfig['db']['driver']>('db.driver')!,
        mysql: {
          host: cs.get<string>('db.mysql.host')!,
          port: cs.get<number>('db.mysql.port')!,
          user: cs.get<string>('db.mysql.user')!,
          password: cs.get<string>('db.mysql.password')!,
          landlordDb: cs.get<string>('db.mysql.landlordDb')!,
          tenantDbPrefix: cs.get<string>('db.mysql.tenantDbPrefix')!,
        },
        postgres: {
          host:               cs.get<string>('db.postgres.host')!,
          port:               cs.get<number>('db.postgres.port')!,
          user:               cs.get<string>('db.postgres.user')!,
          password:           cs.get<string>('db.postgres.password')!,
          database:           cs.get<string>('db.postgres.database')!,
          landlordSchema:     cs.get<string>('db.postgres.landlordSchema')!,
          tenantSchemaPrefix: cs.get<string>('db.postgres.tenantSchemaPrefix')!,
        },
        sqlite: {
          dataDir: cs.get<string>('db.sqlite.dataDir')!,
          landlordFile: cs.get<string>('db.sqlite.landlordFile')!,
          tenantDir: cs.get<string>('db.sqlite.tenantDir')!,
        },
      },
      webOrigin: cs.get<string>('webOrigin')!,
    };
  }

  @Global()
  @Module({
    providers: [
      {
        provide: LANDLORD_DATA_SOURCE,
        useFactory: async (cs: ConfigService): Promise<DataSource> => {
          const cfg = buildAppConfig(cs);
          return createLandlordDataSource(cfg);
        },
        inject: [ConfigService],
      },
      TenantConnectionService,
    ],
    exports: [LANDLORD_DATA_SOURCE, TenantConnectionService],
  })
  export class DatabaseModule {}
  