import Firebird from "node-firebird";
import { IBusinessTransaction } from "../../domain/repositories";
import { InfrastructureError } from "../InfrastructureError";

export type FirebirdBusinessTransactionType = IBusinessTransaction & {
  start: (a: unknown) => unknown;
  complete(
    work: (t: Firebird.Transaction, db: Firebird.Database) => unknown,
  ): void;
};

export class FirebirdBusinessTransaction
  implements FirebirdBusinessTransactionType
{
  private _connection: Firebird.ConnectionPool;

  constructor(connection: Firebird.ConnectionPool) {
    this._connection = connection;
  }

  public start() {
    return this;
  }

  public complete(
    work: (t: Firebird.Transaction, db?: Firebird.Database) => unknown,
  ): void {
    this._connection.get((err, db: Firebird.Database) => {
      if (err) {
        InfrastructureError.create(InfrastructureError.UNEXCEPTED_ERROR, err);
      }

      db.transaction(
        Firebird.ISOLATION_READ_COMMITTED,
        (err, transaction: Firebird.Transaction) => {
          if (err) {
            InfrastructureError.create(
              InfrastructureError.UNEXCEPTED_ERROR,
              err,
            );
          }

          try {
            work(transaction, db);
            transaction.commit();
          } catch (e: unknown) {
            transaction.rollback();
          } finally {
            db.detach();
          }
        },
      );
    });
  }
}
