import { TransactionCommitEvent } from './event/TransactionCommitEvent';
import { TransactionRollbackEvent } from './event/TransactionRollbackEvent';
import { TransactionStartEvent } from './event/TransactionStartEvent';
import { UpdateEvent } from './event/UpdateEvent';
import { RemoveEvent } from './event/RemoveEvent';
import { InsertEvent } from './event/InsertEvent';
import { LoadEvent } from './event/LoadEvent';
import { SoftRemoveEvent } from './event/SoftRemoveEvent';
import { RecoverEvent } from './event/RecoverEvent';
import { AfterQueryEvent, BeforeQueryEvent } from './event/QueryEvent';

/**
 * Classes that implement this interface are subscribers that subscribe for the specific events in the ORM.
 */
export interface EntitySubscriberInterface<Entity = any> {
	/**
	 * Returns the class of the entity to which events will listen.
	 * If this method is omitted, then subscriber will listen to events of all entities.
	 */
	listenTo?(): Function | string;

	/**
	 * Called after entity is loaded from the database.
	 *
	 * For backward compatibility this signature is slightly different from the
	 * others.  `event` was added later but is always provided (it is only
	 * optional in the signature so that its introduction does not break
	 * compilation for existing subscribers).
	 */
	afterLoad?(entity: Entity, event?: LoadEvent<Entity>): Promise<any> | void;

	/**
	 * Called before query is executed.
	 */
	beforeQuery?(event: BeforeQueryEvent<Entity>): Promise<any> | void;

	/**
	 * Called after query is executed.
	 */
	afterQuery?(event: AfterQueryEvent<Entity>): Promise<any> | void;

	/**
	 * Called before entity is inserted to the database.
	 */
	beforeInsert?(event: InsertEvent<Entity>): Promise<any> | void;

	/**
	 * Called after entity is inserted to the database.
	 */
	afterInsert?(event: InsertEvent<Entity>): Promise<any> | void;

	/**
	 * Called before entity is updated in the database.
	 */
	beforeUpdate?(event: UpdateEvent<Entity>): Promise<any> | void;

	/**
	 * Called after entity is updated in the database.
	 */
	afterUpdate?(event: UpdateEvent<Entity>): Promise<any> | void;

	/**
	 * Called before entity is removed from the database.
	 */
	beforeRemove?(event: RemoveEvent<Entity>): Promise<any> | void;

	/**
	 * Called before entity is soft removed from the database.
	 */
	beforeSoftRemove?(event: SoftRemoveEvent<Entity>): Promise<any> | void;

	/**
	 * Called before entity is recovered in the database.
	 */
	beforeRecover?(event: RecoverEvent<Entity>): Promise<any> | void;

	/**
	 * Called after entity is removed from the database.
	 */
	afterRemove?(event: RemoveEvent<Entity>): Promise<any> | void;

	/**
	 * Called after entity is soft removed from the database.
	 */
	afterSoftRemove?(event: SoftRemoveEvent<Entity>): Promise<any> | void;

	/**
	 * Called after entity is recovered in the database.
	 */
	afterRecover?(event: RecoverEvent<Entity>): Promise<any> | void;

	/**
	 * Called before transaction is started.
	 */
	beforeTransactionStart?(event: TransactionStartEvent): Promise<any> | void;

	/**
	 * Called after transaction is started.
	 */
	afterTransactionStart?(event: TransactionStartEvent): Promise<any> | void;

	/**
	 * Called before transaction is committed.
	 */
	beforeTransactionCommit?(event: TransactionCommitEvent): Promise<any> | void;

	/**
	 * Called after transaction is committed.
	 */
	afterTransactionCommit?(event: TransactionCommitEvent): Promise<any> | void;

	/**
	 * Called before transaction rollback.
	 */
	beforeTransactionRollback?(event: TransactionRollbackEvent): Promise<any> | void;

	/**
	 * Called after transaction rollback.
	 */
	afterTransactionRollback?(event: TransactionRollbackEvent): Promise<any> | void;
}
