import { Logger } from '@nestjs/common';
import { ClientConfigInterface } from './client-config.interface';

export class ClientConnector {
  constructor(
    private readonly config: ClientConfigInterface,
    private readonly client: { connect: () => Promise<void> },
    private readonly serviceName: string,
    private readonly context: string,
  ) {}

  public async connect(): Promise<void> {
    try {
      await this.client.connect();
      Logger.log(`Connected to ${this.serviceName}`, this.context);
    } catch (err) {
      await this.retryConnection(0);
    }
  }

  private async retryConnection(retries: number): Promise<void> {
    setTimeout(async () => {
      const newRetries = retries + 1;
      Logger.log(
        `Retrying ${this.serviceName} connection: ${newRetries}th time`,
        this.context,
      );

      try {
        await this.client.connect();
        Logger.log(`Connected to ${this.serviceName}`, this.context);
      } catch (err) {
        await this.retryConnection(newRetries);
      }
    }, this.getRetryTime(retries));
  }

  private getRetryTime(retries: number) {
    const time = this.config.INITIAL_RETRY_TIMEOUT_MS * 2 ** retries;
    return time > this.config.MAX_RETRY_TIME_MS
      ? this.config.MAX_RETRY_TIME_MS
      : time;
  }
}
