import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
import { logger } from "../monitoring/logger.js";
class FrameLifecycleHooksRegistry {
  closeHooks = [];
  createHooks = [];
  /**
   * Register a hook to be called when a frame is closed
   * @param name - Unique name for the hook (for logging/debugging)
   * @param handler - Async function to call when frame closes
   * @param priority - Higher priority hooks run first (default: 0)
   */
  onFrameClosed(name, handler, priority = 0) {
    const hook = { name, handler, priority };
    this.closeHooks.push(hook);
    this.closeHooks.sort((a, b) => b.priority - a.priority);
    logger.debug("Registered frame close hook", { name, priority });
    return () => {
      this.closeHooks = this.closeHooks.filter((h) => h !== hook);
      logger.debug("Unregistered frame close hook", { name });
    };
  }
  /**
   * Register a hook to be called when a frame is created
   * @param name - Unique name for the hook (for logging/debugging)
   * @param handler - Async function to call when frame is created
   * @param priority - Higher priority hooks run first (default: 0)
   */
  onFrameCreated(name, handler, priority = 0) {
    const hook = { name, handler, priority };
    this.createHooks.push(hook);
    this.createHooks.sort((a, b) => b.priority - a.priority);
    logger.debug("Registered frame create hook", { name, priority });
    return () => {
      this.createHooks = this.createHooks.filter((h) => h !== hook);
      logger.debug("Unregistered frame create hook", { name });
    };
  }
  /**
   * Trigger all close hooks (called by FrameManager)
   * Hooks are fire-and-forget - errors don't affect frame closure
   */
  async triggerClose(data) {
    if (this.closeHooks.length === 0) return;
    const results = await Promise.allSettled(
      this.closeHooks.map(async (hook) => {
        try {
          await hook.handler(data);
        } catch (error) {
          logger.warn(`Frame close hook "${hook.name}" failed`, {
            error: error instanceof Error ? error.message : String(error),
            frameId: data.frame.frame_id,
            frameName: data.frame.name
          });
        }
      })
    );
    const failed = results.filter((r) => r.status === "rejected").length;
    if (failed > 0) {
      logger.debug("Some frame close hooks failed", {
        total: this.closeHooks.length,
        failed,
        frameId: data.frame.frame_id
      });
    }
  }
  /**
   * Trigger all create hooks (called by FrameManager)
   * Hooks are fire-and-forget - errors don't affect frame creation
   */
  async triggerCreate(frame) {
    if (this.createHooks.length === 0) return;
    const results = await Promise.allSettled(
      this.createHooks.map(async (hook) => {
        try {
          await hook.handler(frame);
        } catch (error) {
          logger.warn(`Frame create hook "${hook.name}" failed`, {
            error: error instanceof Error ? error.message : String(error),
            frameId: frame.frame_id,
            frameName: frame.name
          });
        }
      })
    );
    const failed = results.filter((r) => r.status === "rejected").length;
    if (failed > 0) {
      logger.debug("Some frame create hooks failed", {
        total: this.createHooks.length,
        failed,
        frameId: frame.frame_id
      });
    }
  }
  /**
   * Get count of registered hooks (useful for testing)
   */
  getHookCounts() {
    return {
      close: this.closeHooks.length,
      create: this.createHooks.length
    };
  }
  /**
   * Clear all hooks (useful for testing)
   */
  clearAll() {
    this.closeHooks = [];
    this.createHooks = [];
    logger.debug("Cleared all frame lifecycle hooks");
  }
}
const frameLifecycleHooks = new FrameLifecycleHooksRegistry();
export {
  frameLifecycleHooks
};
//# sourceMappingURL=frame-lifecycle-hooks.js.map
