import { Init, Inject, Provide, Scope, ScopeEnum } from '@midwayjs/decorator';
import { DataSourceManager } from '@midwayjs/core';
import * as oracledb from 'oracledb';
import { DataSourceEntity } from '../entity/sys/data_source';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';

@Provide()
@Scope(ScopeEnum.Singleton)
export class OracleDataSourceManager extends DataSourceManager<oracledb.Pool> {
  options = {
    dataSource: {
      // dataSource0: {
      //   user: 'root',
      //   password: '123456',
      //   connectString: '127.0.0.1:1521/cr-mysql',
      // },
    },
    // 其他配置
  };
  @Inject()
  baseDir: string;
  @InjectEntityModel(DataSourceEntity)
  dataSourceEntity: Repository<DataSourceEntity>;
  @Init()
  async init() {
    try {
      const dataSources = await this.dataSourceEntity.find({
        where: { type: 0 },
      });
      dataSources.map(e => {
        const dataSource = {
          user: e.user,
          password: e.password,
          connectString: e.host + ':' + e.port + '/' + e.database,
        };
        this.options.dataSource['dataSource' + e.id] = dataSource;
      });
      await this.initDataSource(this.options, this.baseDir);
      console.log('Connection pool started');
    } catch (err) {
      console.error('init() error: ' + err.message);
    }
  }
  //创建单个实例
  public async createDataSource(
    config: any,
    dataSourceName: string
  ): Promise<oracledb.Pool> {
    return oracledb.createPool(config);
  }

  getName(): string {
    return 'oracledb';
  }

  protected async checkConnected(dataSource: oracledb.Pool): Promise<boolean> {
    //伪代码
    // return dataSource.status === 'connected';
    return true;
  }

  protected async destroyDataSource(dataSource: oracledb.Pool): Promise<void> {
    if (await this.checkConnected(dataSource)) {
      await dataSource.close();
    }
  }
  async closePoolAndExit() {
    console.log('\nTerminating');
    try {
      // Get the pool from the pool cache and close it when no
      // connections are in use, or force it closed after 10 seconds.
      // If this hangs, you may need DISABLE_OOB=ON in a sqlnet.ora file.
      // This setting should not be needed if both Oracle Client and Oracle
      // Database are 19c (or later).
      await oracledb.getPool().close(10);
      console.log('Pool closed');
      process.exit(0);
    } catch (err) {
      console.error(err.message);
      process.exit(1);
    }
  }
}
