import { DatabaseConnector, ConnectionConfig } from '../interfaces/DatabaseConnector';
import { PostgreSQLConnector } from './PostgreSQLConnector';
import { MariaDBConnector } from './MariaDBConnector';
import { MSSQLConnector } from './MSSQLConnector';
import { OracleConnector } from './OracleConnector';
import { RestApiConnector, RestApiConfig } from './RestApiConnector';

export class DatabaseConnectorFactory {
  private static connectors = new Map<string, DatabaseConnector>();

  static async createConnector(
    type: string,
    config: ConnectionConfig,
    connectionId: number // Added connectionId for unique key
  ): Promise<DatabaseConnector> {
    const key = `${type}-${connectionId}`; // Use connectionId for unique key
    if (this.connectors.has(key)) {
      return this.connectors.get(key)!;
    }

    let connector: DatabaseConnector;

    switch (type.toLowerCase()) {
      case 'postgresql':
        connector = new PostgreSQLConnector(config);
        break;
      case 'mariadb':
      case 'mysql':  // mysql 타입도 MariaDB 커넥터 사용
        connector = new MariaDBConnector(config);
        break;
      case 'mssql':
        connector = new MSSQLConnector(config);
        break;
      case 'oracle':
        connector = new OracleConnector(config);
        break;
      case 'restapi':
        connector = new RestApiConnector(config as RestApiConfig);
        break;
      // Add other database types here
      default:
        throw new Error(`지원하지 않는 데이터베이스 타입: ${type}`);
    }

    this.connectors.set(key, connector);
    return connector;
  }

  static async getConnector(connectionId: number, type: string): Promise<DatabaseConnector | undefined> {
    const key = `${type}-${connectionId}`;
    return this.connectors.get(key);
  }

  static async closeConnector(connectionId: number, type: string): Promise<void> {
    const key = `${type}-${connectionId}`;
    const connector = this.connectors.get(key);
    if (connector) {
      await connector.disconnect();
      this.connectors.delete(key);
    }
  }

  static async closeAll(): Promise<void> {
    for (const connector of this.connectors.values()) {
      await connector.disconnect();
    }
    this.connectors.clear();
  }
}