// packages/backend/src/modules/netaclaw/browser-daemon/runtime/session-registry.ts
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';

export interface SessionEntry {
  sessionName: string;
  context: any;
  lastUsedAt: Date;
}

@Provide()
@Scope(ScopeEnum.Singleton)
export class SessionRegistry {
  private entries = new Map<string, SessionEntry>();
  private locks = new Map<string, Promise<void>>();

  register(sessionName: string, context: any): void {
    this.entries.set(sessionName, { sessionName, context, lastUsedAt: new Date() });
  }

  unregister(sessionName: string): void {
    this.entries.delete(sessionName);
  }

  has(sessionName: string): boolean {
    return this.entries.has(sessionName);
  }

  get(sessionName: string): any | undefined {
    return this.entries.get(sessionName)?.context;
  }

  touch(sessionName: string): void {
    const e = this.entries.get(sessionName);
    if (e) e.lastUsedAt = new Date();
  }

  list(): SessionEntry[] {
    return [...this.entries.values()];
  }

  async withLock<T>(sessionName: string, fn: () => Promise<T>): Promise<T> {
    const prev = this.locks.get(sessionName) ?? Promise.resolve();
    let release!: () => void;
    const next = new Promise<void>(r => (release = r));
    this.locks.set(sessionName, prev.then(() => next));
    try {
      await prev;
      return await fn();
    } finally {
      release();
      if (this.locks.get(sessionName) === next) this.locks.delete(sessionName);
    }
  }
}
